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

#include "chrome/browser/views/options/cookies_view.h"

#include <algorithm>

#include "app/gfx/canvas.h"
#include "app/gfx/color_utils.h"
#include "app/l10n_util.h"
#include "base/i18n/time_formatting.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "chrome/browser/cookies_tree_model.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/views/cookie_info_view.h"
#include "chrome/browser/views/database_info_view.h"
#include "chrome/browser/views/local_storage_info_view.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "net/base/cookie_monster.h"
#include "views/border.h"
#include "views/grid_layout.h"
#include "views/controls/label.h"
#include "views/controls/button/native_button.h"
#include "views/controls/tree/tree_view.h"
#include "views/controls/textfield/textfield.h"
#include "views/standard_layout.h"

// static
views::Window* CookiesView::instance_ = NULL;
static const int kSearchFilterDelayMs = 500;

///////////////////////////////////////////////////////////////////////////////
// CookiesTreeView
//  Overridden to handle Delete key presses

class CookiesTreeView : public views::TreeView {
 public:
  explicit CookiesTreeView(CookiesTreeModel* cookies_model);
  virtual ~CookiesTreeView() {}

  // Removes the items associated with the selected node in the TreeView
  void RemoveSelectedItems();

 private:
  DISALLOW_COPY_AND_ASSIGN(CookiesTreeView);
};

CookiesTreeView::CookiesTreeView(CookiesTreeModel* cookies_model) {
  SetModel(cookies_model);
  SetRootShown(false);
  SetEditable(false);
}

void CookiesTreeView::RemoveSelectedItems() {
  TreeModelNode* selected_node = GetSelectedNode();
  if (selected_node) {
    static_cast<CookiesTreeModel*>(model())->DeleteCookieNode(
        static_cast<CookieTreeNode*>(GetSelectedNode()));
  }
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, public:

// static
void CookiesView::ShowCookiesWindow(Profile* profile) {
  if (!instance_) {
    CookiesView* cookies_view = new CookiesView(profile);
    instance_ = views::Window::CreateChromeWindow(
        NULL, gfx::Rect(), cookies_view);
  }
  if (!instance_->IsVisible()) {
    instance_->Show();
  } else {
    instance_->Activate();
  }
}

CookiesView::~CookiesView() {
  cookies_tree_->SetModel(NULL);
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, TreeModelObserver overrides:

void CookiesView::TreeNodesAdded(TreeModel* model,
                                 TreeModelNode* parent,
                                 int start,
                                 int count) {
  UpdateRemoveButtonsState();
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, views::Buttonlistener implementation:

void CookiesView::ButtonPressed(
    views::Button* sender, const views::Event& event) {
  if (sender == remove_button_) {
    cookies_tree_->RemoveSelectedItems();
    if (cookies_tree_model_->GetRoot()->GetChildCount() == 0)
      UpdateForEmptyState();
  } else if (sender == remove_all_button_) {
    cookies_tree_model_->DeleteAllStoredObjects();
    UpdateForEmptyState();
  } else if (sender == clear_search_button_) {
    ResetSearchQuery();
  }
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, views::Textfield::Controller implementation:

void CookiesView::ContentsChanged(views::Textfield* sender,
                                  const std::wstring& new_contents) {
  clear_search_button_->SetEnabled(!search_field_->text().empty());
  search_update_factory_.RevokeAll();
  MessageLoop::current()->PostDelayedTask(FROM_HERE,
      search_update_factory_.NewRunnableMethod(
          &CookiesView::UpdateSearchResults), kSearchFilterDelayMs);
}

bool CookiesView::HandleKeystroke(views::Textfield* sender,
                                  const views::Textfield::Keystroke& key) {
  if (key.GetKeyboardCode() == base::VKEY_ESCAPE) {
    ResetSearchQuery();
  } else if (key.GetKeyboardCode() == base::VKEY_RETURN) {
    search_update_factory_.RevokeAll();
    UpdateSearchResults();
  }
  return false;
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, views::DialogDelegate implementation:

std::wstring CookiesView::GetWindowTitle() const {
  return l10n_util::GetString(IDS_COOKIES_WEBSITE_PERMISSIONS_WINDOW_TITLE);
}

void CookiesView::WindowClosing() {
  instance_ = NULL;
}

views::View* CookiesView::GetContentsView() {
  return this;
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, views::View overrides:

void CookiesView::Layout() {
  // Lay out the Remove/Remove All buttons in the parent view.
  gfx::Size ps = remove_button_->GetPreferredSize();
  gfx::Rect parent_bounds = GetParent()->GetLocalBounds(false);
  int y_buttons = parent_bounds.bottom() - ps.height() - kButtonVEdgeMargin;

  remove_button_->SetBounds(kPanelHorizMargin, y_buttons, ps.width(),
                            ps.height());

  ps = remove_all_button_->GetPreferredSize();
  int remove_all_x = remove_button_->x() + remove_button_->width() +
      kRelatedControlHorizontalSpacing;
  remove_all_button_->SetBounds(remove_all_x, y_buttons, ps.width(),
                                ps.height());

  // Lay out this View
  View::Layout();
}

gfx::Size CookiesView::GetPreferredSize() {
  return gfx::Size(views::Window::GetLocalizedContentsSize(
      IDS_COOKIES_DIALOG_WIDTH_CHARS,
      IDS_COOKIES_DIALOG_HEIGHT_LINES));
}

void CookiesView::ViewHierarchyChanged(bool is_add,
                                       views::View* parent,
                                       views::View* child) {
  if (is_add && child == this)
    Init();
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, views::TreeViewController overrides:

void CookiesView::OnTreeViewSelectionChanged(views::TreeView* tree_view) {
  CookieTreeNode::DetailedInfo detailed_info =
      static_cast<CookieTreeNode*>(tree_view->GetSelectedNode())->
      GetDetailedInfo();
  if (detailed_info.node_type == CookieTreeNode::DetailedInfo::TYPE_COOKIE) {
    UpdateVisibleDetailedInfo(cookie_info_view_);
    cookie_info_view_->SetCookie(detailed_info.cookie->first,
                                 detailed_info.cookie->second);
  } else if (detailed_info.node_type ==
             CookieTreeNode::DetailedInfo::TYPE_DATABASE) {
    UpdateVisibleDetailedInfo(database_info_view_);
    database_info_view_->SetDatabaseInfo(*detailed_info.database_info);
  } else if (detailed_info.node_type ==
             CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE) {
    UpdateVisibleDetailedInfo(local_storage_info_view_);
    local_storage_info_view_->SetLocalStorageInfo(
        *detailed_info.local_storage_info);
  } else {
    UpdateVisibleDetailedInfo(cookie_info_view_);
    cookie_info_view_->ClearCookieDisplay();
  }
}

void CookiesView::OnTreeViewKeyDown(base::KeyboardCode keycode) {
  if (keycode == base::VKEY_DELETE)
    cookies_tree_->RemoveSelectedItems();
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, public:

void CookiesView::UpdateSearchResults() {
  cookies_tree_model_->UpdateSearchResults(search_field_->text());
  remove_button_->SetEnabled(cookies_tree_model_->GetRoot()->
      GetTotalNodeCount() > 1);
  remove_all_button_->SetEnabled(cookies_tree_model_->GetRoot()->
      GetTotalNodeCount() > 1);
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, private:

CookiesView::CookiesView(Profile* profile)
    :
      search_label_(NULL),
      search_field_(NULL),
      clear_search_button_(NULL),
      description_label_(NULL),
      cookies_tree_(NULL),
      cookie_info_view_(NULL),
      database_info_view_(NULL),
      local_storage_info_view_(NULL),
      remove_button_(NULL),
      remove_all_button_(NULL),
      profile_(profile),
      ALLOW_THIS_IN_INITIALIZER_LIST(search_update_factory_(this)) {
}

void CookiesView::Init() {
  search_label_ = new views::Label(
      l10n_util::GetString(IDS_COOKIES_SEARCH_LABEL));
  search_field_ = new views::Textfield;
  search_field_->SetController(this);
  clear_search_button_ = new views::NativeButton(
      this, l10n_util::GetString(IDS_COOKIES_CLEAR_SEARCH_LABEL));
  clear_search_button_->SetEnabled(false);
  description_label_ = new views::Label(
      l10n_util::GetString(IDS_COOKIES_INFO_LABEL));
  description_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
  cookies_tree_model_.reset(new CookiesTreeModel(profile_,
      new BrowsingDataDatabaseHelper(profile_),
      new BrowsingDataLocalStorageHelper(profile_)));
  cookies_tree_model_->AddObserver(this);
  cookie_info_view_ = new CookieInfoView(false);
  database_info_view_ = new DatabaseInfoView;
  local_storage_info_view_ = new LocalStorageInfoView;
  cookies_tree_ = new CookiesTreeView(cookies_tree_model_.get());
  remove_button_ = new views::NativeButton(
      this, l10n_util::GetString(IDS_COOKIES_REMOVE_LABEL));
  remove_all_button_ = new views::NativeButton(
      this, l10n_util::GetString(IDS_COOKIES_REMOVE_ALL_LABEL));

  using views::GridLayout;
  using views::ColumnSet;

  GridLayout* layout = CreatePanelGridLayout(this);
  SetLayoutManager(layout);

  const int five_column_layout_id = 0;
  ColumnSet* column_set = layout->AddColumnSet(five_column_layout_id);
  column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0,
                        GridLayout::USE_PREF, 0, 0);
  column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
                        GridLayout::USE_PREF, 0, 0);
  column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0,
                        GridLayout::USE_PREF, 0, 0);

  const int single_column_layout_id = 1;
  column_set = layout->AddColumnSet(single_column_layout_id);
  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
                        GridLayout::USE_PREF, 0, 0);

  layout->StartRow(0, five_column_layout_id);
  layout->AddView(search_label_);
  layout->AddView(search_field_);
  layout->AddView(clear_search_button_);
  layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing);

  layout->StartRow(0, single_column_layout_id);
  layout->AddView(description_label_);

  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
  layout->StartRow(1, single_column_layout_id);
  cookies_tree_->set_lines_at_root(true);
  cookies_tree_->set_auto_expand_children(true);
  layout->AddView(cookies_tree_);

  cookies_tree_->SetController(this);

  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
  layout->StartRow(0, single_column_layout_id);
  layout->AddView(cookie_info_view_, 1, 2);

  layout->StartRow(0, single_column_layout_id);
  layout->AddView(database_info_view_);

  layout->StartRow(0, single_column_layout_id);
  layout->AddView(local_storage_info_view_);

  // Add the Remove/Remove All buttons to the ClientView
  View* parent = GetParent();
  parent->AddChildView(remove_button_);
  parent->AddChildView(remove_all_button_);
  if (!cookies_tree_model_.get()->GetRoot()->GetChildCount())
    UpdateForEmptyState();
  else
    UpdateVisibleDetailedInfo(cookie_info_view_);
}

void CookiesView::ResetSearchQuery() {
  search_field_->SetText(std::wstring());
  clear_search_button_->SetEnabled(false);
  UpdateSearchResults();
}

void CookiesView::UpdateForEmptyState() {
  cookie_info_view_->ClearCookieDisplay();
  remove_button_->SetEnabled(false);
  remove_all_button_->SetEnabled(false);
  UpdateVisibleDetailedInfo(cookie_info_view_);
}

void CookiesView::UpdateRemoveButtonsState() {
  remove_button_->SetEnabled(cookies_tree_model_->GetRoot()->
      GetTotalNodeCount() > 1);
  remove_all_button_->SetEnabled(cookies_tree_model_->GetRoot()->
      GetTotalNodeCount() > 1);
}

void CookiesView::UpdateVisibleDetailedInfo(views::View* view) {
  cookie_info_view_->SetVisible(view == cookie_info_view_);
  database_info_view_->SetVisible(view == database_info_view_);
  local_storage_info_view_->SetVisible(view == local_storage_info_view_);
}
<commit_msg>Fixes a bug where the "remove" and "remove all" buttons are enabled in the "Cookies" page even when there is nothing selected in the tree view.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/views/options/cookies_view.h"

#include <algorithm>

#include "app/gfx/canvas.h"
#include "app/gfx/color_utils.h"
#include "app/l10n_util.h"
#include "base/i18n/time_formatting.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "chrome/browser/cookies_tree_model.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/views/cookie_info_view.h"
#include "chrome/browser/views/database_info_view.h"
#include "chrome/browser/views/local_storage_info_view.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "net/base/cookie_monster.h"
#include "views/border.h"
#include "views/grid_layout.h"
#include "views/controls/label.h"
#include "views/controls/button/native_button.h"
#include "views/controls/tree/tree_view.h"
#include "views/controls/textfield/textfield.h"
#include "views/standard_layout.h"

// static
views::Window* CookiesView::instance_ = NULL;
static const int kSearchFilterDelayMs = 500;

///////////////////////////////////////////////////////////////////////////////
// CookiesTreeView
//  Overridden to handle Delete key presses

class CookiesTreeView : public views::TreeView {
 public:
  explicit CookiesTreeView(CookiesTreeModel* cookies_model);
  virtual ~CookiesTreeView() {}

  // Removes the items associated with the selected node in the TreeView
  void RemoveSelectedItems();

 private:
  DISALLOW_COPY_AND_ASSIGN(CookiesTreeView);
};

CookiesTreeView::CookiesTreeView(CookiesTreeModel* cookies_model) {
  SetModel(cookies_model);
  SetRootShown(false);
  SetEditable(false);
}

void CookiesTreeView::RemoveSelectedItems() {
  TreeModelNode* selected_node = GetSelectedNode();
  if (selected_node) {
    static_cast<CookiesTreeModel*>(model())->DeleteCookieNode(
        static_cast<CookieTreeNode*>(GetSelectedNode()));
  }
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, public:

// static
void CookiesView::ShowCookiesWindow(Profile* profile) {
  if (!instance_) {
    CookiesView* cookies_view = new CookiesView(profile);
    instance_ = views::Window::CreateChromeWindow(
        NULL, gfx::Rect(), cookies_view);
  }
  if (!instance_->IsVisible()) {
    instance_->Show();
  } else {
    instance_->Activate();
  }
}

CookiesView::~CookiesView() {
  cookies_tree_->SetModel(NULL);
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, TreeModelObserver overrides:

void CookiesView::TreeNodesAdded(TreeModel* model,
                                 TreeModelNode* parent,
                                 int start,
                                 int count) {
  UpdateRemoveButtonsState();
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, views::Buttonlistener implementation:

void CookiesView::ButtonPressed(
    views::Button* sender, const views::Event& event) {
  if (sender == remove_button_) {
    cookies_tree_->RemoveSelectedItems();
    if (cookies_tree_model_->GetRoot()->GetChildCount() == 0)
      UpdateForEmptyState();
  } else if (sender == remove_all_button_) {
    cookies_tree_model_->DeleteAllStoredObjects();
    UpdateForEmptyState();
  } else if (sender == clear_search_button_) {
    ResetSearchQuery();
  }
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, views::Textfield::Controller implementation:

void CookiesView::ContentsChanged(views::Textfield* sender,
                                  const std::wstring& new_contents) {
  clear_search_button_->SetEnabled(!search_field_->text().empty());
  search_update_factory_.RevokeAll();
  MessageLoop::current()->PostDelayedTask(FROM_HERE,
      search_update_factory_.NewRunnableMethod(
          &CookiesView::UpdateSearchResults), kSearchFilterDelayMs);
}

bool CookiesView::HandleKeystroke(views::Textfield* sender,
                                  const views::Textfield::Keystroke& key) {
  if (key.GetKeyboardCode() == base::VKEY_ESCAPE) {
    ResetSearchQuery();
  } else if (key.GetKeyboardCode() == base::VKEY_RETURN) {
    search_update_factory_.RevokeAll();
    UpdateSearchResults();
  }
  return false;
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, views::DialogDelegate implementation:

std::wstring CookiesView::GetWindowTitle() const {
  return l10n_util::GetString(IDS_COOKIES_WEBSITE_PERMISSIONS_WINDOW_TITLE);
}

void CookiesView::WindowClosing() {
  instance_ = NULL;
}

views::View* CookiesView::GetContentsView() {
  return this;
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, views::View overrides:

void CookiesView::Layout() {
  // Lay out the Remove/Remove All buttons in the parent view.
  gfx::Size ps = remove_button_->GetPreferredSize();
  gfx::Rect parent_bounds = GetParent()->GetLocalBounds(false);
  int y_buttons = parent_bounds.bottom() - ps.height() - kButtonVEdgeMargin;

  remove_button_->SetBounds(kPanelHorizMargin, y_buttons, ps.width(),
                            ps.height());

  ps = remove_all_button_->GetPreferredSize();
  int remove_all_x = remove_button_->x() + remove_button_->width() +
      kRelatedControlHorizontalSpacing;
  remove_all_button_->SetBounds(remove_all_x, y_buttons, ps.width(),
                                ps.height());

  // Lay out this View
  View::Layout();
}

gfx::Size CookiesView::GetPreferredSize() {
  return gfx::Size(views::Window::GetLocalizedContentsSize(
      IDS_COOKIES_DIALOG_WIDTH_CHARS,
      IDS_COOKIES_DIALOG_HEIGHT_LINES));
}

void CookiesView::ViewHierarchyChanged(bool is_add,
                                       views::View* parent,
                                       views::View* child) {
  if (is_add && child == this)
    Init();
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, views::TreeViewController overrides:

void CookiesView::OnTreeViewSelectionChanged(views::TreeView* tree_view) {
  UpdateRemoveButtonsState();
  CookieTreeNode::DetailedInfo detailed_info =
      static_cast<CookieTreeNode*>(tree_view->GetSelectedNode())->
      GetDetailedInfo();
  if (detailed_info.node_type == CookieTreeNode::DetailedInfo::TYPE_COOKIE) {
    UpdateVisibleDetailedInfo(cookie_info_view_);
    cookie_info_view_->SetCookie(detailed_info.cookie->first,
                                 detailed_info.cookie->second);
  } else if (detailed_info.node_type ==
             CookieTreeNode::DetailedInfo::TYPE_DATABASE) {
    UpdateVisibleDetailedInfo(database_info_view_);
    database_info_view_->SetDatabaseInfo(*detailed_info.database_info);
  } else if (detailed_info.node_type ==
             CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE) {
    UpdateVisibleDetailedInfo(local_storage_info_view_);
    local_storage_info_view_->SetLocalStorageInfo(
        *detailed_info.local_storage_info);
  } else {
    UpdateVisibleDetailedInfo(cookie_info_view_);
    cookie_info_view_->ClearCookieDisplay();
  }
}

void CookiesView::OnTreeViewKeyDown(base::KeyboardCode keycode) {
  if (keycode == base::VKEY_DELETE)
    cookies_tree_->RemoveSelectedItems();
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, public:

void CookiesView::UpdateSearchResults() {
  cookies_tree_model_->UpdateSearchResults(search_field_->text());
  remove_button_->SetEnabled(cookies_tree_model_->GetRoot()->
      GetTotalNodeCount() > 1);
  remove_all_button_->SetEnabled(cookies_tree_model_->GetRoot()->
      GetTotalNodeCount() > 1);
}

///////////////////////////////////////////////////////////////////////////////
// CookiesView, private:

CookiesView::CookiesView(Profile* profile)
    :
      search_label_(NULL),
      search_field_(NULL),
      clear_search_button_(NULL),
      description_label_(NULL),
      cookies_tree_(NULL),
      cookie_info_view_(NULL),
      database_info_view_(NULL),
      local_storage_info_view_(NULL),
      remove_button_(NULL),
      remove_all_button_(NULL),
      profile_(profile),
      ALLOW_THIS_IN_INITIALIZER_LIST(search_update_factory_(this)) {
}

void CookiesView::Init() {
  search_label_ = new views::Label(
      l10n_util::GetString(IDS_COOKIES_SEARCH_LABEL));
  search_field_ = new views::Textfield;
  search_field_->SetController(this);
  clear_search_button_ = new views::NativeButton(
      this, l10n_util::GetString(IDS_COOKIES_CLEAR_SEARCH_LABEL));
  clear_search_button_->SetEnabled(false);
  description_label_ = new views::Label(
      l10n_util::GetString(IDS_COOKIES_INFO_LABEL));
  description_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
  cookies_tree_model_.reset(new CookiesTreeModel(profile_,
      new BrowsingDataDatabaseHelper(profile_),
      new BrowsingDataLocalStorageHelper(profile_)));
  cookies_tree_model_->AddObserver(this);
  cookie_info_view_ = new CookieInfoView(false);
  database_info_view_ = new DatabaseInfoView;
  local_storage_info_view_ = new LocalStorageInfoView;
  cookies_tree_ = new CookiesTreeView(cookies_tree_model_.get());
  remove_button_ = new views::NativeButton(
      this, l10n_util::GetString(IDS_COOKIES_REMOVE_LABEL));
  remove_all_button_ = new views::NativeButton(
      this, l10n_util::GetString(IDS_COOKIES_REMOVE_ALL_LABEL));

  using views::GridLayout;
  using views::ColumnSet;

  GridLayout* layout = CreatePanelGridLayout(this);
  SetLayoutManager(layout);

  const int five_column_layout_id = 0;
  ColumnSet* column_set = layout->AddColumnSet(five_column_layout_id);
  column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0,
                        GridLayout::USE_PREF, 0, 0);
  column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
                        GridLayout::USE_PREF, 0, 0);
  column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0,
                        GridLayout::USE_PREF, 0, 0);

  const int single_column_layout_id = 1;
  column_set = layout->AddColumnSet(single_column_layout_id);
  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
                        GridLayout::USE_PREF, 0, 0);

  layout->StartRow(0, five_column_layout_id);
  layout->AddView(search_label_);
  layout->AddView(search_field_);
  layout->AddView(clear_search_button_);
  layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing);

  layout->StartRow(0, single_column_layout_id);
  layout->AddView(description_label_);

  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
  layout->StartRow(1, single_column_layout_id);
  cookies_tree_->set_lines_at_root(true);
  cookies_tree_->set_auto_expand_children(true);
  layout->AddView(cookies_tree_);

  cookies_tree_->SetController(this);

  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
  layout->StartRow(0, single_column_layout_id);
  layout->AddView(cookie_info_view_, 1, 2);

  layout->StartRow(0, single_column_layout_id);
  layout->AddView(database_info_view_);

  layout->StartRow(0, single_column_layout_id);
  layout->AddView(local_storage_info_view_);

  // Add the Remove/Remove All buttons to the ClientView
  View* parent = GetParent();
  parent->AddChildView(remove_button_);
  parent->AddChildView(remove_all_button_);
  if (!cookies_tree_model_.get()->GetRoot()->GetChildCount())
    UpdateForEmptyState();
  else
    UpdateVisibleDetailedInfo(cookie_info_view_);
}

void CookiesView::ResetSearchQuery() {
  search_field_->SetText(std::wstring());
  clear_search_button_->SetEnabled(false);
  UpdateSearchResults();
}

void CookiesView::UpdateForEmptyState() {
  cookie_info_view_->ClearCookieDisplay();
  remove_button_->SetEnabled(false);
  remove_all_button_->SetEnabled(false);
  UpdateVisibleDetailedInfo(cookie_info_view_);
}

void CookiesView::UpdateRemoveButtonsState() {
  remove_button_->SetEnabled(cookies_tree_model_->GetRoot()->
      GetTotalNodeCount() > 1 && cookies_tree_->GetSelectedNode());
  remove_all_button_->SetEnabled(cookies_tree_model_->GetRoot()->
      GetTotalNodeCount() > 1 && cookies_tree_->GetSelectedNode());
}

void CookiesView::UpdateVisibleDetailedInfo(views::View* view) {
  cookie_info_view_->SetVisible(view == cookie_info_view_);
  database_info_view_->SetVisible(view == database_info_view_);
  local_storage_info_view_->SetVisible(view == local_storage_info_view_);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: BUsers.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: oj $ $Date: 2001-10-12 11:59:33 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_ADABAS_USERS_HXX_
#define _CONNECTIVITY_ADABAS_USERS_HXX_

#ifndef _CONNECTIVITY_SDBCX_COLLECTION_HXX_
#include "connectivity/sdbcx/VCollection.hxx"
#endif
namespace connectivity
{
    namespace sdbcx
    {
        class IRefreshableUsers;
    }
    namespace adabas
    {
        class OAdabasConnection;
        class OUsers : public sdbcx::OCollection
        {
            OAdabasConnection*    m_pConnection;
            connectivity::sdbcx::IRefreshableUsers* m_pParent;
        public:
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNamed > createObject(const ::rtl::OUString& _rName);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > createEmptyObject();
            virtual void impl_refresh() throw(::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNamed > cloneObject(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _xDescriptor);
            virtual void appendObject( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor );
            virtual void dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName);
        public:
            OUsers( ::cppu::OWeakObject& _rParent,
                    ::osl::Mutex& _rMutex,
                    const TStringVector &_rVector,
                    OAdabasConnection* _pConnection,
                    connectivity::sdbcx::IRefreshableUsers* _pParent) : sdbcx::OCollection(_rParent,sal_True,_rMutex,_rVector)
                ,m_pConnection(_pConnection)
                ,m_pParent(_pParent)
            {}

        };
    }
}

#endif // _CONNECTIVITY_ADABAS_USERS_HXX_

<commit_msg>INTEGRATION: CWS dba24 (1.4.262); FILE MERGED 2005/02/09 08:07:50 oj 1.4.262.1: #i26950# remove the need for XNamed<commit_after>/*************************************************************************
 *
 *  $RCSfile: BUsers.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: vg $ $Date: 2005-03-10 15:34:48 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_ADABAS_USERS_HXX_
#define _CONNECTIVITY_ADABAS_USERS_HXX_

#ifndef _CONNECTIVITY_SDBCX_COLLECTION_HXX_
#include "connectivity/sdbcx/VCollection.hxx"
#endif
namespace connectivity
{
    namespace sdbcx
    {
        class IRefreshableUsers;
    }
    namespace adabas
    {
        class OAdabasConnection;
        class OUsers : public sdbcx::OCollection
        {
            OAdabasConnection*    m_pConnection;
            connectivity::sdbcx::IRefreshableUsers* m_pParent;
        public:
            virtual sdbcx::ObjectType createObject(const ::rtl::OUString& _rName);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > createEmptyObject();
            virtual void impl_refresh() throw(::com::sun::star::uno::RuntimeException);
            virtual void appendObject( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor );
            virtual void dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName);
        public:
            OUsers( ::cppu::OWeakObject& _rParent,
                    ::osl::Mutex& _rMutex,
                    const TStringVector &_rVector,
                    OAdabasConnection* _pConnection,
                    connectivity::sdbcx::IRefreshableUsers* _pParent) : sdbcx::OCollection(_rParent,sal_True,_rMutex,_rVector)
                ,m_pConnection(_pConnection)
                ,m_pParent(_pParent)
            {}

        };
    }
}

#endif // _CONNECTIVITY_ADABAS_USERS_HXX_

<|endoftext|>


<commit_before>/*!
 * \file gauss_structure.hpp
 * \brief Headers of the Finite Element structure (gaussian points)
 *        The subroutines and functions are in the gauss_structure.cpp file.
 * \author R. Sanchez
 * \version 6.1.0 "Falcon"
 *
 * The current SU2 release has been coordinated by the
 * SU2 International Developers Society <www.su2devsociety.org>
 * with selected contributions from the open-source community.
 *
 * The main research teams contributing to the current release are:
 *  - Prof. Juan J. Alonso's group at Stanford University.
 *  - Prof. Piero Colonna's group at Delft University of Technology.
 *  - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology.
 *  - Prof. Alberto Guardone's group at Polytechnic University of Milan.
 *  - Prof. Rafael Palacios' group at Imperial College London.
 *  - Prof. Vincent Terrapon's group at the University of Liege.
 *  - Prof. Edwin van der Weide's group at the University of Twente.
 *  - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics.
 *
 * Copyright 2012-2018, Francisco D. Palacios, Thomas D. Economon,
 *                      Tim Albring, and the SU2 contributors.
 *
 * SU2 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; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * SU2 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 SU2. If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "mpi_structure.hpp"

#include <cmath>
#include <iostream>
#include <cstdlib>

#include "config_structure.hpp"
#include "geometry_structure.hpp"

using namespace std;

/*!
 * \class CGaussVariable
 * \brief Main class for defining the gaussian points.
 * \author R. Sanchez
 */
class CGaussVariable {
protected:

	su2double **GradNi_Xj,		// Gradient of the shape functions N[i] respect to the reference configuration
	**GradNi_xj;			// Gradient of the shape functions N[i] respect to the current configuration
	su2double *Ni;				// Shape functions N[i] at the gaussian point
	su2double J_X,				// Jacobian of the element evaluated at the current Gauss Point respect to the reference configuration
	J_x;					// Jacobian of the element evaluated at the current Gauss Point respect to the current configuration
	unsigned short iGaussPoint;	// Identifier of the Gauss point considered

public:

	/*!
	 * \brief Constructor of the class.
	 */
	CGaussVariable(void);

  /*!
	 * \overload
	 * \param[in] val_nvar - Number of variables of the problem.
	 * \param[in] config - Definition of the particular problem.
	 */
	//CGaussVariable(unsigned short val_nvar, CConfig *config);

   /*!
	  * \overload
	  * \param[in] val_iGauss - ID of the Gaussian Point
	  * \param[in] val_nDim - Number of dimensions of the problem.
	  * \param[in] config - Definition of the particular problem.
	*/
	CGaussVariable(unsigned short val_iGauss, unsigned short val_nDim, unsigned short val_nNodes);

	/*!
	 * \brief Destructor of the class.
	 */
	virtual ~CGaussVariable(void);

	void SetGradNi_Xj(su2double val_GradNi_Xj, unsigned short val_iDim, unsigned short val_Ni);

	void SetGradNi_xj(su2double val_GradNi_xj, unsigned short val_iDim, unsigned short val_Ni);

	void SetNi(su2double val_ShapeNi, unsigned short val_Ni);

	void SetJ_X(su2double valJ_X);

	void SetJ_x(su2double valJ_x);

	su2double **GetGradNi_Xj(void);

	su2double GetGradNi_Xj(unsigned short val_Ni, unsigned short val_iDim);

	su2double GetGradNi_xj(unsigned short val_Ni, unsigned short val_iDim);

	su2double GetNi(unsigned short val_Ni);

	su2double GetJ_X(void);

	su2double GetJ_x(void);

	unsigned short Get_iGauss(void);

};

/*!
 * \class CElementProperty
 * \brief Main class for defining the element properties.
 * \author R. Sanchez
 * \version 6.1.0 "Falcon"
 */
class CElementProperty {
protected:

  unsigned long iMat_Mod;               /*!< \brief Index of the material model used. */
  unsigned long iMat_Prop;              /*!< \brief Index of the properties (E, Nu) for the structural model used. */
  unsigned long iElectric_Prop;         /*!< \brief Index of the electric properties (Em) for the structural model used. */
  unsigned long iDV;                    /*!< \brief Index of the group of design variables to which the element belongs. */
  su2double design_rho;                 /*!< \brief Value of the design density for material-based topology optimization. */
  su2double physical_rho;               /*!< \brief Value of the physical density for material-based topology optimization. */

public:

  /*!
   * \brief Constructor of the class.
   */
  CElementProperty(void);

   /*!
    * \overload
    * \param[in] val_iGauss - ID of the Gaussian Point
    * \param[in] val_nDim - Number of dimensions of the problem.
    * \param[in] config - Definition of the particular problem.
  */
  CElementProperty(unsigned long valMat_Model, unsigned long valMat_Prop, unsigned long valElectric_Prop, unsigned long valDV, su2double valDensity = 1.0);

  /*!
   * \brief Destructor of the class.
   */
  virtual ~CElementProperty(void);

  unsigned long GetMat_Mod(void);

  unsigned long GetMat_Prop(void);

  unsigned long GetElectric_Prop(void);

  unsigned long GetDV(void);

  void SetDesignDensity(su2double valDensity);

  su2double GetDesignDensity(void);

  void SetPhysicalDensity(su2double valDensity);

  su2double GetPhysicalDensity(void);

  su2double GetAdjointDensity(void);

  void RegisterDensity(void);
};

#include "gauss_structure.inl"
<commit_msg>added comments to the ElementProperties class methods<commit_after>/*!
 * \file gauss_structure.hpp
 * \brief Headers of the Finite Element structure (gaussian points)
 *        The subroutines and functions are in the gauss_structure.cpp file.
 * \author R. Sanchez
 * \version 6.1.0 "Falcon"
 *
 * The current SU2 release has been coordinated by the
 * SU2 International Developers Society <www.su2devsociety.org>
 * with selected contributions from the open-source community.
 *
 * The main research teams contributing to the current release are:
 *  - Prof. Juan J. Alonso's group at Stanford University.
 *  - Prof. Piero Colonna's group at Delft University of Technology.
 *  - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology.
 *  - Prof. Alberto Guardone's group at Polytechnic University of Milan.
 *  - Prof. Rafael Palacios' group at Imperial College London.
 *  - Prof. Vincent Terrapon's group at the University of Liege.
 *  - Prof. Edwin van der Weide's group at the University of Twente.
 *  - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics.
 *
 * Copyright 2012-2018, Francisco D. Palacios, Thomas D. Economon,
 *                      Tim Albring, and the SU2 contributors.
 *
 * SU2 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; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * SU2 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 SU2. If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "mpi_structure.hpp"

#include <cmath>
#include <iostream>
#include <cstdlib>

#include "config_structure.hpp"
#include "geometry_structure.hpp"

using namespace std;

/*!
 * \class CGaussVariable
 * \brief Main class for defining the gaussian points.
 * \author R. Sanchez
 */
class CGaussVariable {
protected:

	su2double **GradNi_Xj,		// Gradient of the shape functions N[i] respect to the reference configuration
	**GradNi_xj;			// Gradient of the shape functions N[i] respect to the current configuration
	su2double *Ni;				// Shape functions N[i] at the gaussian point
	su2double J_X,				// Jacobian of the element evaluated at the current Gauss Point respect to the reference configuration
	J_x;					// Jacobian of the element evaluated at the current Gauss Point respect to the current configuration
	unsigned short iGaussPoint;	// Identifier of the Gauss point considered

public:

	/*!
	 * \brief Constructor of the class.
	 */
	CGaussVariable(void);

  /*!
	 * \overload
	 * \param[in] val_nvar - Number of variables of the problem.
	 * \param[in] config - Definition of the particular problem.
	 */
	//CGaussVariable(unsigned short val_nvar, CConfig *config);

   /*!
	  * \overload
	  * \param[in] val_iGauss - ID of the Gaussian Point
	  * \param[in] val_nDim - Number of dimensions of the problem.
	  * \param[in] config - Definition of the particular problem.
	*/
	CGaussVariable(unsigned short val_iGauss, unsigned short val_nDim, unsigned short val_nNodes);

	/*!
	 * \brief Destructor of the class.
	 */
	virtual ~CGaussVariable(void);

	void SetGradNi_Xj(su2double val_GradNi_Xj, unsigned short val_iDim, unsigned short val_Ni);

	void SetGradNi_xj(su2double val_GradNi_xj, unsigned short val_iDim, unsigned short val_Ni);

	void SetNi(su2double val_ShapeNi, unsigned short val_Ni);

	void SetJ_X(su2double valJ_X);

	void SetJ_x(su2double valJ_x);

	su2double **GetGradNi_Xj(void);

	su2double GetGradNi_Xj(unsigned short val_Ni, unsigned short val_iDim);

	su2double GetGradNi_xj(unsigned short val_Ni, unsigned short val_iDim);

	su2double GetNi(unsigned short val_Ni);

	su2double GetJ_X(void);

	su2double GetJ_x(void);

	unsigned short Get_iGauss(void);

};

/*!
 * \class CElementProperty
 * \brief Main class for defining the element properties.
 * \author R. Sanchez
 * \version 6.1.0 "Falcon"
 */
class CElementProperty {
protected:

  unsigned long iMat_Mod;               /*!< \brief Index of the material model used. */
  unsigned long iMat_Prop;              /*!< \brief Index of the properties (E, Nu) for the structural model used. */
  unsigned long iElectric_Prop;         /*!< \brief Index of the electric properties (Em) for the structural model used. */
  unsigned long iDV;                    /*!< \brief Index of the group of design variables to which the element belongs. */
  su2double design_rho;                 /*!< \brief Value of the design density for material-based topology optimization. */
  su2double physical_rho;               /*!< \brief Value of the physical density for material-based topology optimization. */

public:

  /*!
   * \brief Default constructor of the class.
   */
  CElementProperty(void);

   /*!
    * \brief Constructor of the class.
    * \param[in] valMat_Model - Type of material model (i.e. numerics) for the element, see FEA_TERM etc. in option_structure.hpp.
    * \param[in] valMat_Prop - Index of the physical properties (E,nu,rho,rho_dead_load) assigned to the element.
    * \param[in] valElectric_Prop - Index of the electric properties.
    * \param[in] valDV - Index of the design variable assigned to the element (bound to a material property by "DESIGN_VARIABLE_FEA").
    * \param[in] valDensity - Value for Design and Physical densities (topology optimization variables).
  */
  CElementProperty(unsigned long valMat_Model, unsigned long valMat_Prop, unsigned long valElectric_Prop, unsigned long valDV, su2double valDensity = 1.0);

  /*!
   * \brief Destructor of the class.
   */
  virtual ~CElementProperty(void);

  /*!
   * \brief Get the material model to use for the element.
   */
  unsigned long GetMat_Mod(void);

  /*!
   * \brief Get index of the physical properties.
   */
  unsigned long GetMat_Prop(void);

  /*!
   * \brief Get index of the electric properties.
   */
  unsigned long GetElectric_Prop(void);

  /*!
   * \brief Get index of the design variable.
   */
  unsigned long GetDV(void);

  /*!
   * \brief Set the Design density (topology optimization variable).
   */
  void SetDesignDensity(su2double valDensity);

  /*!
   * \brief Get the value of the Design density.
   */
  su2double GetDesignDensity(void);

  /*!
   * \brief Set the Physical density (used to penalize element stiffness by the FEM solver).
   */
  void SetPhysicalDensity(su2double valDensity);

  /*!
   * \brief Get the value of the Physical density.
   */
  su2double GetPhysicalDensity(void);

  /*!
   * \brief Extract the derivative of the Design density.
   */
  su2double GetAdjointDensity(void);

  /*!
   * \brief Register the Design density as an AD input variable.
   */
  void RegisterDensity(void);
};

#include "gauss_structure.inl"
<|endoftext|>


<commit_before>#include "ui_stylesheet.h"

#include "ui_colour_scheme.h"
#include "halley/file_formats/config_file.h"
#include "halley/audio/audio_clip.h"
#include "halley/core/graphics/text/font.h"
#include "halley/core/resources/resources.h"
#include "halley/support/logger.h"
#include "halley/maths/vector4.h"
using namespace Halley;

Colour4f getColour(const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme)
{
	if (node.getType() != ConfigNodeType::String) {
		return Colour4f(1, 1, 1, 1);
	}

	const auto& str = node.asString();
	if (str.startsWith("#")) {
		return Colour4f::fromString(str);
	} else if (colourScheme) {
		return colourScheme->getColour(str);
	} else {
		Logger::logWarning("Invalid colour: \"" + str + "\"");
		return Colour4f();
	}
}

template <typename T>
void loadStyleData(Resources& resources, const String& name, const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme, T& data) {}

template <>
void loadStyleData(Resources& resources, const String& name, const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme, Sprite& data)
{
	if (node.getType() == ConfigNodeType::String) {
		if (!node.asString().isEmpty()) {
			data = Sprite().setImage(resources, node.asString());
		}
	} else {
		data = Sprite()
			.setImage(resources, node["img"].asString())
			.setColour(getColour(node["colour"], colourScheme));
	}
}

template <>
void loadStyleData(Resources& resources, const String& name, const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme, TextRenderer& data)
{
	data = TextRenderer()
		.setFont(resources.get<Font>(node["font"].asString()))
		.setSize(node["size"].asFloat())
		.setColour(getColour(node["colour"], colourScheme))
		.setOutline(node["outline"].asFloat(0.0f))
		.setOutlineColour(Colour4f::fromString(node["outlineColour"].asString("#000000")))
		.setAlignment(node["alignment"].asFloat(0.0f))
		.setSmoothness(node["smoothness"].asFloat(1.0));
}

template <>
void loadStyleData(Resources& resources, const String& name, const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme, String& data)
{
	if (node.asString().isEmpty()) {
		data = "";
	} else {
		data = node.asString();
	}
}

template <>
void loadStyleData(Resources& resources, const String& name, const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme, Vector4f& data)
{
	auto& vals = node.asSequence();
	data = Vector4f(vals[0].asFloat(), vals[1].asFloat(), vals[2].asFloat(), vals[3].asFloat());
}

template <>
void loadStyleData(Resources& resources, const String& name, const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme, float& data)
{
	data = node.asFloat();
}

template <>
void loadStyleData(Resources& resources, const String& name, const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme, Colour4f& data)
{
	data = getColour(node, colourScheme);
}

template <>
void loadStyleData(Resources& resources, const String& name, const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme, std::shared_ptr<const UIStyleDefinition>& data)
{
	if (node.getType() != ConfigNodeType::Map) {
		data = {};
	} else {
		data = std::make_shared<UIStyleDefinition>(name, node, resources, colourScheme);
	}
}

template <typename T>
const T& getValue(const ConfigNode* node, Resources& resources, const String& name, const String& key, std::shared_ptr<const UIColourScheme> colourScheme, std::unordered_map<String, T>& cache)
{
	Expects(node);
	node->assertValid();

	// Is it already in cache?
	const auto iter = cache.find(key);
	if (iter != cache.end()) {
		return iter->second;
	}

	// Not in cache, try to load it
	if (node->hasKey(key)) {
		T data;
		loadStyleData(resources, key, (*node)[key], colourScheme, data);
		cache[key] = data;
		return cache[key];
	} else {
		// Not found. Use a default.
		const auto iter2 = cache.find(":default");
		if (iter2 != cache.end()) {
			Logger::logWarning(String(typeid(T).name()) + " not found in UI style: " + name + "." + key);
			return iter2->second;
		} else {
			throw Exception(String(typeid(T).name()) + " not found in UI style: " + name + "." + key + ". Additionally, default was not set.", HalleyExceptions::Tools);
		}
	}
}

template <typename T>
bool hasValue(const ConfigNode* node, Resources& resources, const String& name, const String& key, std::unordered_map<String, T>& cache)
{
	// Is it already in cache?
	const auto iter = cache.find(key);
	if (iter != cache.end()) {
		return true;
	}

	return node->hasKey(key);
}

class UIStyleDefinition::Pimpl {
public:
	mutable std::unordered_map<String, Sprite> sprites;
	mutable std::unordered_map<String, TextRenderer> textRenderers;
	mutable std::unordered_map<String, Vector4f> borders;
	mutable std::unordered_map<String, String> strings;
	mutable std::unordered_map<String, float> floats;
	mutable std::unordered_map<String, Colour4f> colours;
	mutable std::unordered_map<String, std::shared_ptr<const UIStyleDefinition>> subStyles;
};

UIStyleDefinition::UIStyleDefinition(String styleName, const ConfigNode& node, Resources& resources, const std::shared_ptr<const UIColourScheme>& colourScheme)
	: styleName(std::move(styleName))
	, node(&node)
	, resources(resources)
	, colourScheme(colourScheme)
	, pimpl(std::make_unique<Pimpl>())
{
	// Load defaults
	pimpl->sprites[":default"] = Sprite();
	pimpl->textRenderers[":default"] = TextRenderer();
	pimpl->floats[":default"] = 0.0f;
	pimpl->borders[":default"] = Vector4f();
	pimpl->strings[":default"] = "";
	pimpl->subStyles[":default"] = {};
	pimpl->colours[":default"] = Colour4f(1, 1, 1, 1);
}

UIStyleDefinition::~UIStyleDefinition() = default;

std::shared_ptr<const UIStyleDefinition> UIStyleDefinition::getSubStyle(const String& name) const
{
	return getValue(node, resources, styleName, name, colourScheme, pimpl->subStyles);
}

const Sprite& UIStyleDefinition::getSprite(const String& name) const
{
	return getValue(node, resources, styleName, name, colourScheme, pimpl->sprites);
}

const TextRenderer& UIStyleDefinition::getTextRenderer(const String& name) const
{
	return getValue(node, resources, styleName, name, colourScheme, pimpl->textRenderers);
}

bool UIStyleDefinition::hasTextRenderer(const String& name) const
{
	return hasValue(node, resources, styleName, name, pimpl->textRenderers);
}

bool UIStyleDefinition::hasColour(const String& name) const
{
	return hasValue(node, resources, styleName, name, pimpl->colours);
}

bool UIStyleDefinition::hasSubStyle(const String& name) const
{
	return hasValue(node, resources, styleName, name, pimpl->subStyles);
}

void UIStyleDefinition::reload(const ConfigNode& node)
{
	this->node = &node;
}

Vector4f UIStyleDefinition::getBorder(const String& name) const
{
	return getValue(node, resources, styleName, name, colourScheme, pimpl->borders);
}

const String& UIStyleDefinition::getString(const String& name) const
{
	return getValue(node, resources, styleName, name, colourScheme, pimpl->strings);
}

float UIStyleDefinition::getFloat(const String& name) const
{
	return getValue(node, resources, styleName, name, colourScheme, pimpl->floats);
}

Colour4f UIStyleDefinition::getColour(const String& name) const
{
	return getValue(node, resources, styleName, name, colourScheme, pimpl->colours);
}

UIStyleSheet::UIStyleSheet(Resources& resources)
	: resources(resources)
{
}

UIStyleSheet::UIStyleSheet(Resources& resources, const ConfigFile& file, std::shared_ptr<const UIColourScheme> colourScheme)
	: resources(resources)
{
	load(file, colourScheme);
}

void UIStyleSheet::load(const ConfigFile& file, std::shared_ptr<const UIColourScheme> colourScheme)
{
	load(file.getRoot(), colourScheme);
	observers[file.getAssetId()] = ConfigObserver(file);
}

bool UIStyleSheet::updateIfNeeded()
{
	if (needsUpdate()) {
		update();
		return true;
	}
	return false;
}

bool UIStyleSheet::needsUpdate() const
{
	for (auto& o: observers) {
		if (o.second.needsUpdate()) {
			return true;
		}
	}
	return false;
}

void UIStyleSheet::update()
{
	for (auto& o: observers) {
		o.second.update();
		load(o.second.getRoot(), lastColourScheme);
	}
}

void UIStyleSheet::load(const ConfigNode& root, std::shared_ptr<const UIColourScheme> colourScheme)
{
	lastColourScheme = colourScheme;

	for (const auto& node: root["uiStyle"].asMap()) {
		// If it already exists, update existing instance (as it might be kept by UI elements all around)
		const auto iter = styles.find(node.first);
		if (iter != styles.end()) {
			iter->second->reload(node.second);
		} else {
			styles[node.first] = std::make_unique<UIStyleDefinition>(node.first, node.second, resources, colourScheme);
		}
	}
}

std::shared_ptr<const UIStyleDefinition> UIStyleSheet::getStyle(const String& styleName) const
{
	auto iter = styles.find(styleName);
	if (iter == styles.end()) {
		throw Exception("Unknown style: " + styleName, HalleyExceptions::UI);
	}
	return iter->second;
}
<commit_msg>Fix last commit<commit_after>#include "ui_stylesheet.h"

#include "ui_colour_scheme.h"
#include "halley/file_formats/config_file.h"
#include "halley/audio/audio_clip.h"
#include "halley/core/graphics/text/font.h"
#include "halley/core/resources/resources.h"
#include "halley/support/logger.h"
#include "halley/maths/vector4.h"
using namespace Halley;

Colour4f getColour(const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme)
{
	if (node.getType() != ConfigNodeType::String) {
		return Colour4f(1, 1, 1, 1);
	}

	const auto& str = node.asString();
	if (str.startsWith("#")) {
		return Colour4f::fromString(str);
	} else if (colourScheme) {
		return colourScheme->getColour(str);
	} else {
		Logger::logWarning("Invalid colour: \"" + str + "\"");
		return Colour4f();
	}
}

template <typename T>
void loadStyleData(Resources& resources, const String& name, const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme, T& data)
{
	throw Exception("Unreachable code", HalleyExceptions::UI);
}

template <>
void loadStyleData(Resources& resources, const String& name, const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme, Sprite& data)
{
	if (node.getType() == ConfigNodeType::String) {
		if (!node.asString().isEmpty()) {
			data = Sprite().setImage(resources, node.asString());
		}
	} else {
		data = Sprite()
			.setImage(resources, node["img"].asString())
			.setColour(getColour(node["colour"], colourScheme));
	}
}

template <>
void loadStyleData(Resources& resources, const String& name, const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme, TextRenderer& data)
{
	data = TextRenderer()
		.setFont(resources.get<Font>(node["font"].asString()))
		.setSize(node["size"].asFloat())
		.setColour(getColour(node["colour"], colourScheme))
		.setOutline(node["outline"].asFloat(0.0f))
		.setOutlineColour(Colour4f::fromString(node["outlineColour"].asString("#000000")))
		.setAlignment(node["alignment"].asFloat(0.0f))
		.setSmoothness(node["smoothness"].asFloat(1.0));
}

template <>
void loadStyleData(Resources& resources, const String& name, const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme, String& data)
{
	if (node.asString().isEmpty()) {
		data = "";
	} else {
		data = node.asString();
	}
}

template <>
void loadStyleData(Resources& resources, const String& name, const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme, Vector4f& data)
{
	auto& vals = node.asSequence();
	data = Vector4f(vals[0].asFloat(), vals[1].asFloat(), vals[2].asFloat(), vals[3].asFloat());
}

template <>
void loadStyleData(Resources& resources, const String& name, const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme, float& data)
{
	data = node.asFloat();
}

template <>
void loadStyleData(Resources& resources, const String& name, const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme, Colour4f& data)
{
	data = getColour(node, colourScheme);
}

template <>
void loadStyleData(Resources& resources, const String& name, const ConfigNode& node, const std::shared_ptr<const UIColourScheme>& colourScheme, std::shared_ptr<UIStyleDefinition>& data)
{
	if (node.getType() != ConfigNodeType::Map) {
		data = {};
	} else {
		data = std::make_shared<UIStyleDefinition>(name, node, resources, colourScheme);
	}
}

template <typename T>
const T& getValue(const ConfigNode* node, Resources& resources, const String& name, const String& key, std::shared_ptr<const UIColourScheme> colourScheme, std::unordered_map<String, T>& cache)
{
	Expects(node);
	node->assertValid();

	// Is it already in cache?
	const auto iter = cache.find(key);
	if (iter != cache.end()) {
		return iter->second;
	}

	// Not in cache, try to load it
	if (node->hasKey(key)) {
		T data;
		loadStyleData(resources, key, (*node)[key], colourScheme, data);
		cache[key] = data;
		return cache[key];
	} else {
		// Not found. Use a default.
		const auto iter2 = cache.find(":default");
		if (iter2 != cache.end()) {
			Logger::logWarning(String(typeid(T).name()) + " not found in UI style: " + name + "." + key);
			return iter2->second;
		} else {
			throw Exception(String(typeid(T).name()) + " not found in UI style: " + name + "." + key + ". Additionally, default was not set.", HalleyExceptions::Tools);
		}
	}
}

template <typename T>
bool hasValue(const ConfigNode* node, Resources& resources, const String& name, const String& key, std::unordered_map<String, T>& cache)
{
	// Is it already in cache?
	const auto iter = cache.find(key);
	if (iter != cache.end()) {
		return true;
	}

	return node->hasKey(key);
}

class UIStyleDefinition::Pimpl {
public:
	mutable std::unordered_map<String, Sprite> sprites;
	mutable std::unordered_map<String, TextRenderer> textRenderers;
	mutable std::unordered_map<String, Vector4f> borders;
	mutable std::unordered_map<String, String> strings;
	mutable std::unordered_map<String, float> floats;
	mutable std::unordered_map<String, Colour4f> colours;
	mutable std::unordered_map<String, std::shared_ptr<UIStyleDefinition>> subStyles;
};

UIStyleDefinition::UIStyleDefinition(String styleName, const ConfigNode& node, Resources& resources, const std::shared_ptr<const UIColourScheme>& colourScheme)
	: styleName(std::move(styleName))
	, node(&node)
	, resources(resources)
	, colourScheme(colourScheme)
	, pimpl(std::make_unique<Pimpl>())
{
	loadDefaults();
}

UIStyleDefinition::~UIStyleDefinition() = default;

std::shared_ptr<const UIStyleDefinition> UIStyleDefinition::getSubStyle(const String& name) const
{
	return getValue(node, resources, styleName, name, colourScheme, pimpl->subStyles);
}

const Sprite& UIStyleDefinition::getSprite(const String& name) const
{
	return getValue(node, resources, styleName, name, colourScheme, pimpl->sprites);
}

const TextRenderer& UIStyleDefinition::getTextRenderer(const String& name) const
{
	return getValue(node, resources, styleName, name, colourScheme, pimpl->textRenderers);
}

bool UIStyleDefinition::hasTextRenderer(const String& name) const
{
	return hasValue(node, resources, styleName, name, pimpl->textRenderers);
}

bool UIStyleDefinition::hasColour(const String& name) const
{
	return hasValue(node, resources, styleName, name, pimpl->colours);
}

bool UIStyleDefinition::hasSubStyle(const String& name) const
{
	return hasValue(node, resources, styleName, name, pimpl->subStyles);
}

void UIStyleDefinition::reload(const ConfigNode& node, std::shared_ptr<const UIColourScheme> colourScheme)
{
	this->colourScheme = std::move(colourScheme);
	this->node = &node;
	loadDefaults();
}

Vector4f UIStyleDefinition::getBorder(const String& name) const
{
	return getValue(node, resources, styleName, name, colourScheme, pimpl->borders);
}

const String& UIStyleDefinition::getString(const String& name) const
{
	return getValue(node, resources, styleName, name, colourScheme, pimpl->strings);
}

float UIStyleDefinition::getFloat(const String& name) const
{
	return getValue(node, resources, styleName, name, colourScheme, pimpl->floats);
}

Colour4f UIStyleDefinition::getColour(const String& name) const
{
	return getValue(node, resources, styleName, name, colourScheme, pimpl->colours);
}

void UIStyleDefinition::loadDefaults()
{
	pimpl->sprites.clear();
	pimpl->sprites[":default"] = Sprite();
	pimpl->textRenderers.clear();
	pimpl->textRenderers[":default"] = TextRenderer();
	pimpl->floats.clear();
	pimpl->floats[":default"] = 0.0f;
	pimpl->borders.clear();
	pimpl->borders[":default"] = Vector4f();
	pimpl->strings.clear();
	pimpl->strings[":default"] = "";
	pimpl->colours[":default"] = Colour4f(1, 1, 1, 1);
	pimpl->colours.clear();

	for (auto& [k, v]: pimpl->subStyles) {
		if (v) {
			v->loadDefaults();
		}
	}
	pimpl->subStyles[":default"] = {};
}

UIStyleSheet::UIStyleSheet(Resources& resources)
	: resources(resources)
{
}

UIStyleSheet::UIStyleSheet(Resources& resources, const ConfigFile& file, std::shared_ptr<const UIColourScheme> colourScheme)
	: resources(resources)
{
	load(file, colourScheme);
}

void UIStyleSheet::load(const ConfigFile& file, std::shared_ptr<const UIColourScheme> colourScheme)
{
	load(file.getRoot(), colourScheme);
	observers[file.getAssetId()] = ConfigObserver(file);
}

bool UIStyleSheet::updateIfNeeded()
{
	if (needsUpdate()) {
		update();
		return true;
	}
	return false;
}

void UIStyleSheet::reload(std::shared_ptr<const UIColourScheme> colourScheme)
{
	lastColourScheme = std::move(colourScheme);
	update();
}

bool UIStyleSheet::needsUpdate() const
{
	for (auto& o: observers) {
		if (o.second.needsUpdate()) {
			return true;
		}
	}
	return false;
}

void UIStyleSheet::update()
{
	for (auto& o: observers) {
		o.second.update();
		load(o.second.getRoot(), lastColourScheme);
	}
}

void UIStyleSheet::load(const ConfigNode& root, std::shared_ptr<const UIColourScheme> colourScheme)
{
	lastColourScheme = colourScheme;

	for (const auto& node: root["uiStyle"].asMap()) {
		// If it already exists, update existing instance (as it might be kept by UI elements all around)
		const auto iter = styles.find(node.first);
		if (iter != styles.end()) {
			iter->second->reload(node.second, colourScheme);
		} else {
			styles[node.first] = std::make_unique<UIStyleDefinition>(node.first, node.second, resources, colourScheme);
		}
	}
}

std::shared_ptr<const UIStyleDefinition> UIStyleSheet::getStyle(const String& styleName) const
{
	auto iter = styles.find(styleName);
	if (iter == styles.end()) {
		throw Exception("Unknown style: " + styleName, HalleyExceptions::UI);
	}
	return iter->second;
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016 zScale Technology GmbH <legal@zscale.io>
 * Authors:
 *   - Paul Asmuth <paul@zscale.io>
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License ("the license") as
 * published by the Free Software Foundation, either version 3 of the License,
 * or any later version.
 *
 * In accordance with Section 7(e) of the license, the licensing of the Program
 * under the license does not imply a trademark license. Therefore any rights,
 * title and interest in our trademarks remain entirely with us.
 *
 * This program 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 license for more details.
 *
 * You can be released from the requirements of the license by purchasing a
 * commercial license. Buying such a license is mandatory as soon as you develop
 * commercial activities involving this program without disclosing the source
 * code of your own applications
 */
#include "eventql/util/stdtypes.h"
#include "eventql/util/application.h"
#include "eventql/util/cli/flagparser.h"
#include "eventql/util/cli/CLI.h"
#include "eventql/util/csv/CSVInputStream.h"
#include "eventql/util/io/file.h"
#include "eventql/util/inspect.h"
#include "eventql/util/human.h"
#include "eventql/io/cstable/cstable_reader.h"
#include "eventql/eventql.h"

int main(int argc, const char** argv) {
  Application::init();

  String filename(argv[1]);
  auto cstable = cstable::CSTableReader::openFile(filename);
  for (const auto& c : cstable->columns()) {
    iputs(
        ">>  column_id=$0, column_name=$1",
        c.column_id,
        c.column_name);
  }

  auto page_mgr = cstable->getPageManager();
  for (const auto& e : page_mgr->getPageIndex()) {
    String type_str;
    switch (e.key.entry_type) {
      case cstable::PageIndexEntryType::DLEVEL:
        type_str = "DLVL";
        break;
      case cstable::PageIndexEntryType::RLEVEL:
        type_str = "RLVL";
        break;
      case cstable::PageIndexEntryType::DATA:
        type_str = "DATA";
        break;
    }

    iputs(
        ">>  column_id=$0 type=$1 offset=$2 size=$3",
        e.key.column_id,
        type_str,
        e.page.offset,
        e.page.size);
  }

  return 0;
}

<commit_msg>improved cstable tool<commit_after>/**
 * Copyright (c) 2016 zScale Technology GmbH <legal@zscale.io>
 * Authors:
 *   - Paul Asmuth <paul@zscale.io>
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License ("the license") as
 * published by the Free Software Foundation, either version 3 of the License,
 * or any later version.
 *
 * In accordance with Section 7(e) of the license, the licensing of the Program
 * under the license does not imply a trademark license. Therefore any rights,
 * title and interest in our trademarks remain entirely with us.
 *
 * This program 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 license for more details.
 *
 * You can be released from the requirements of the license by purchasing a
 * commercial license. Buying such a license is mandatory as soon as you develop
 * commercial activities involving this program without disclosing the source
 * code of your own applications
 */
#include "eventql/util/stdtypes.h"
#include "eventql/util/application.h"
#include "eventql/util/cli/flagparser.h"
#include "eventql/util/cli/CLI.h"
#include "eventql/util/csv/CSVInputStream.h"
#include "eventql/util/io/file.h"
#include "eventql/util/inspect.h"
#include "eventql/util/human.h"
#include "eventql/io/cstable/cstable_reader.h"
#include "eventql/eventql.h"

int main(int argc, const char** argv) {
  Application::init();

  String filename(argv[1]);
  auto cstable = cstable::CSTableReader::openFile(filename);
  iputs("== GENERAL ==\n >> number of records: $0", cstable->numRecords());

  iputs("\n\n== INDEX ==", 1);
  for (const auto& c : cstable->columns()) {
    iputs(
        ">>  column_id=$0, column_name=$1",
        c.column_id,
        c.column_name);
  }

  auto page_mgr = cstable->getPageManager();
  for (const auto& e : page_mgr->getPageIndex()) {
    String type_str;
    switch (e.key.entry_type) {
      case cstable::PageIndexEntryType::DLEVEL:
        type_str = "DLVL";
        break;
      case cstable::PageIndexEntryType::RLEVEL:
        type_str = "RLVL";
        break;
      case cstable::PageIndexEntryType::DATA:
        type_str = "DATA";
        break;
    }

    iputs(
        ">>  column_id=$0 type=$1 offset=$2 size=$3",
        e.key.column_id,
        type_str,
        e.page.offset,
        e.page.size);
  }

  for (const auto& c : cstable->columns()) {
    iputs(
        "\n\n== COLUMN DATA for $0/$1 ==",
        c.column_id,
        c.column_name);

    auto col_reader = cstable->getColumnReader(c.column_name);
    uint64_t rlevel;
    uint64_t dlevel;
    String data;
    for (auto i = cstable->numRecords(); i--; ) {
      col_reader->readString(&rlevel, &dlevel, &data);
      iputs(">>  rlvl=$0 dlvl=$1 data=($2) '$3'", rlevel, dlevel, data.size(), data);
    }
  }

  return 0;
}

<|endoftext|>


<commit_before>/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2020 Hugo Beauzée-Luyssen, Videolabs, VideoLAN
 *
 * Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
 *
 * This program 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; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program 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 program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#if HAVE_CONFIG_H
# include "config.h"
#endif

#include "filesystem/libvlc/DeviceLister.h"
#include "utils/VLCInstance.h"
#include "utils/Filename.h"
#include "utils/Url.h"
#include "filesystem/libvlc/Device.h"

#include "logging/Logger.h"

namespace medialibrary
{
namespace fs
{
namespace libvlc
{

DeviceLister::DeviceLister( const std::string &protocol )
    : m_protocol( protocol )
    , m_cb( nullptr )
{
}

void DeviceLister::refresh()
{
    /*
     * We are continuously refreshing through libvlc's discoverer so there's
     * nothing particular to do here
     */
}

bool DeviceLister::start( IDeviceListerCb *cb )
{
    assert( m_cb == nullptr );
    m_cb = cb;
    auto started = false;

    for ( auto& sd : m_sds )
    {
        auto& em = sd.discoverer.mediaList()->eventManager();
        em.onItemAdded( [this]( VLC::MediaPtr m, int ) { onDeviceAdded( std::move( m ) ); } );
        em.onItemDeleted( [this]( VLC::MediaPtr m, int ) { onDeviceRemoved( std::move( m ) ); } );
        if ( sd.discoverer.start() == false )
            LOG_WARN( "Failed to start SD ", sd.name );
        else if ( started == false )
            started = true;
    }

    return started;
}

void DeviceLister::stop()
{
    for ( auto& sd : m_sds )
        sd.discoverer.stop();
}

void DeviceLister::addSD( const std::string& name )
{
    m_sds.push_back( SD{
        name,
        VLC::MediaDiscoverer{ VLCInstance::get(), name }
    } );
}

void DeviceLister::onDeviceAdded( VLC::MediaPtr media )
{
    const auto& mrl = media->mrl();
    if ( utils::url::scheme( mrl ) != m_protocol )
        return;

    auto uuid = utils::url::stripScheme( mrl );
    LOG_DEBUG( "Mountpoint added: ", mrl, " from device ", uuid );
    m_cb->onDeviceMounted( uuid, utils::file::toFolderPath( mrl ), true );
}

void DeviceLister::onDeviceRemoved( VLC::MediaPtr media )
{
    const auto& mrl = media->mrl();
    if ( utils::url::scheme( mrl ) != m_protocol )
        return;

    auto uuid = utils::url::stripScheme( mrl );
    LOG_DEBUG( "Mountpoint removed: ", mrl, " from device ", uuid );

    m_cb->onDeviceUnmounted( uuid, utils::file::toFolderPath( mrl ) );
}

}
}
}
<commit_msg>libvlc: DeviceLister: Fix device UUID extraction<commit_after>/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2020 Hugo Beauzée-Luyssen, Videolabs, VideoLAN
 *
 * Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
 *
 * This program 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; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program 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 program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#if HAVE_CONFIG_H
# include "config.h"
#endif

#include "filesystem/libvlc/DeviceLister.h"
#include "utils/VLCInstance.h"
#include "utils/Filename.h"
#include "utils/Url.h"
#include "filesystem/libvlc/Device.h"

#include "logging/Logger.h"

namespace medialibrary
{
namespace fs
{
namespace libvlc
{

DeviceLister::DeviceLister( const std::string &protocol )
    : m_protocol( protocol )
    , m_cb( nullptr )
{
}

void DeviceLister::refresh()
{
    /*
     * We are continuously refreshing through libvlc's discoverer so there's
     * nothing particular to do here
     */
}

bool DeviceLister::start( IDeviceListerCb *cb )
{
    assert( m_cb == nullptr );
    m_cb = cb;
    auto started = false;

    for ( auto& sd : m_sds )
    {
        auto& em = sd.discoverer.mediaList()->eventManager();
        em.onItemAdded( [this]( VLC::MediaPtr m, int ) { onDeviceAdded( std::move( m ) ); } );
        em.onItemDeleted( [this]( VLC::MediaPtr m, int ) { onDeviceRemoved( std::move( m ) ); } );
        if ( sd.discoverer.start() == false )
            LOG_WARN( "Failed to start SD ", sd.name );
        else if ( started == false )
            started = true;
    }

    return started;
}

void DeviceLister::stop()
{
    for ( auto& sd : m_sds )
        sd.discoverer.stop();
}

void DeviceLister::addSD( const std::string& name )
{
    m_sds.push_back( SD{
        name,
        VLC::MediaDiscoverer{ VLCInstance::get(), name }
    } );
}

void DeviceLister::onDeviceAdded( VLC::MediaPtr media )
{
    const auto& mrl = media->mrl();
    if ( utils::url::scheme( mrl ) != m_protocol )
        return;

    auto uuid = media->meta( libvlc_meta_Title );
    LOG_DEBUG( "Mountpoint added: ", mrl, " from device ", uuid );
    m_cb->onDeviceMounted( uuid, utils::file::toFolderPath( mrl ), true );
}

void DeviceLister::onDeviceRemoved( VLC::MediaPtr media )
{
    const auto& mrl = media->mrl();
    if ( utils::url::scheme( mrl ) != m_protocol )
        return;

    auto uuid = media->meta( libvlc_meta_Title );
    LOG_DEBUG( "Mountpoint removed: ", mrl, " from device ", uuid );

    m_cb->onDeviceUnmounted( uuid, utils::file::toFolderPath( mrl ) );
}

}
}
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: basicbox.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2004-07-06 12:18:39 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <ide_pch.hxx>

#pragma hdrstop

#include <basidesh.hrc>
#include <basidesh.hxx>
#define _SVSTDARR_STRINGS
#include <svtools/svstdarr.hxx>
#include <basobj.hxx>

#include <basicbox.hxx>
#include <iderid.hxx>
#include <iderdll.hxx>
#include <bastypes.hxx>

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XDISPATCHPROVIDER_HPP_
#include <com/sun/star/frame/XDispatchProvider.hpp>
#endif

using namespace ::com::sun::star;

SFX_IMPL_TOOLBOX_CONTROL( LibBoxControl, SfxStringItem );

LibBoxControl::LibBoxControl( USHORT nSlotId, USHORT nId, ToolBox& rTbx )
    : SfxToolBoxControl( nSlotId, nId, rTbx )
{
}

LibBoxControl::~LibBoxControl()
{
}

void LibBoxControl::StateChanged( USHORT nSID, SfxItemState eState, const SfxPoolItem* pState )
{
    BasicLibBox* pBox = (BasicLibBox*) GetToolBox().GetItemWindow( GetId() );

    DBG_ASSERT( pBox, "Box not found" );
    if ( !pBox )
        return;

    if ( eState != SFX_ITEM_AVAILABLE )
        pBox->Disable();
    else
    {
        pBox->Enable();

        if ( pState->ISA(SfxStringItem) )
            pBox->Update( (const SfxStringItem*)pState );
        else
            pBox->Update( NULL );
    }
}

Window* LibBoxControl::CreateItemWindow( Window *pParent )
{
    return new BasicLibBox( pParent, m_xFrame );
}

BasicLibBox::BasicLibBox( Window* pParent, const uno::Reference< frame::XFrame >& rFrame ) :
    ListBox( pParent, WinBits( WB_BORDER | WB_DROPDOWN ) ),
    m_xFrame( rFrame )
{
    FillBox();
    bIgnoreSelect = TRUE;   // Select von 0 noch nicht weiterleiten
    bFillBox = TRUE;
    SelectEntryPos( 0 );
    aCurText = GetEntry( 0 );
    SetSizePixel( Size( 165, 200 ) );
    bIgnoreSelect = FALSE;
    StartListening( *SFX_APP(), TRUE /* Nur einmal anmelden */ );
}

__EXPORT BasicLibBox::~BasicLibBox()
{
}

void __EXPORT BasicLibBox::Update( const SfxStringItem* pItem )
{
    // Immer auf dem laufenden sein...
//  if ( !pItem  || !pItem->GetValue().Len() )
        FillBox();

    if ( pItem )
    {
        aCurText = pItem->GetValue();
        if ( aCurText.Len() == 0 )
            aCurText = String( IDEResId( RID_STR_ALL ) );
    }

    if ( GetSelectEntry() != aCurText )
        SelectEntry( aCurText );
}

void __EXPORT BasicLibBox::ReleaseFocus()
{
    SfxViewShell* pCurSh = SfxViewShell::Current();
    DBG_ASSERT( pCurSh, "Current ViewShell not found!" );

    if ( pCurSh )
    {
        Window* pShellWin = pCurSh->GetWindow();
        if ( !pShellWin )       // sonst werde ich ihn nicht los
            pShellWin = Application::GetDefDialogParent();

        pShellWin->GrabFocus();
    }
}

void __EXPORT BasicLibBox::SFX_NOTIFY(  SfxBroadcaster& rBC, const TypeId&,
                                        const SfxHint& rHint, const TypeId& )
{
    if ( rHint.IsA( TYPE( SfxEventHint ) ) )
    {
        if ( ( ((SfxEventHint&)rHint).GetEventId() == SFX_EVENT_CREATEDOC ) ||
             ( ((SfxEventHint&)rHint).GetEventId() == SFX_EVENT_OPENDOC ) )
        {
            FillBox();  // IDE reagiert selbst, wenn == aktuelle Lib
        }
        else if ( ((SfxEventHint&)rHint).GetEventId() == SFX_EVENT_SAVEASDOC )
        {
            // Wenn das aktuell angezeigte Doc umbenannt wird...
            // Funktioniert nicht, da ich den alten Namen nicht bekomme
//          String aCurLib( GetLibFromMgrAndLib( aCurText ) );
//          String aCurMgr( GetMgrFromMgrAndLib( aCurText ) );
//          String aCurDoc = SfxObjectShell::Current()->GetTitle();
//          if ( aCurMgr == aCurDoc )
//          {
//              FillBox( FALSE );
//              aCurText = CreateMgrAndLibStr( aCurDoc, aCurLib );
//              bIgnoreSelect = TRUE;
//              SelectEntry( aCurText );
//              InfoBox( 0, aCurText ).Execute();
//              bIgnoreSelect = FALSE;
//          }
//          else
                FillBox( TRUE );

        }
        else if ( ((SfxEventHint&)rHint).GetEventId() == SFX_EVENT_CLOSEDOC )
        {
            if ( SFX_APP()->IsInBasicCall() )   // Nicht wenn Office beendet
                FillBox();
        }
    }
}

void BasicLibBox::FillBox( BOOL bSelect )
{
    SetUpdateMode( FALSE );
    bIgnoreSelect = TRUE;

    aCurText = GetSelectEntry();
    USHORT nCurPos = GetSelectEntryPos();

    SelectEntryPos( 0 );
    Clear();

    SvStrings* pStrings = BasicIDE::CreateBasicLibBoxEntries();
    for ( USHORT n = 0; n < pStrings->Count(); n++ )
    {
        String* pStr = pStrings->GetObject( n );
        InsertEntry( *pStr, LISTBOX_APPEND );
    }
    pStrings->DeleteAndDestroy( 0, pStrings->Count() );
    delete pStrings;

    SetUpdateMode( TRUE );

    if ( bSelect )
    {
        SelectEntry( aCurText );
        if ( !GetSelectEntryCount() )
        {
            SelectEntryPos( GetEntryCount() );  // gibst es nicht => leer?
            aCurText = GetSelectEntry();
        }
    }
    bIgnoreSelect = FALSE;
}

long BasicLibBox::PreNotify( NotifyEvent& rNEvt )
{
    long nDone = 0;
    if( rNEvt.GetType() == EVENT_KEYINPUT )
    {
        KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
        USHORT nKeyCode = aKeyEvt.GetKeyCode().GetCode();
        switch( nKeyCode )
        {
            case KEY_RETURN:
            {
                NotifyIDE();
                nDone = 1;
            }
            break;

            case KEY_ESCAPE:
            {
                SelectEntry( aCurText );
                ReleaseFocus();
                nDone = 1;
            }
            break;
        }
    }
    else if( rNEvt.GetType() == EVENT_GETFOCUS )
    {
        if ( bFillBox )
        {
            FillBox();
            bFillBox = FALSE;
        }
    }
    else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
    {
        if ( !HasChildPathFocus( TRUE ) )
        {
            bIgnoreSelect = TRUE;
            bFillBox = TRUE;
        }
    }

    return nDone ? nDone : ListBox::PreNotify( rNEvt );
}

void __EXPORT BasicLibBox::Select()
{
    if ( !IsTravelSelect() )
    {
        if ( !bIgnoreSelect )
            NotifyIDE();
        else
            SelectEntry( aCurText );    // Seit 306... (Select nach Escape)
    }
}

void BasicLibBox::NotifyIDE()
{
    String aLib;
    if ( GetSelectEntryPos() )
        aLib = GetSelectEntry();

    SfxStringItem aLibName( SID_BASICIDE_ARG_LIBNAME, aLib );

    uno::Any a;
    uno::Sequence< beans::PropertyValue > aArgs( 1 );
    aArgs[0].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LibSelect" ));
    aLibName.QueryValue( a );
    aArgs[0].Value = a;
    SfxToolBoxControl::Dispatch(
        uno::Reference< frame::XDispatchProvider >( m_xFrame->getController(), uno::UNO_QUERY ),
        rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:LibSelect" )),
        aArgs );
/*
    BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
    SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
    SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;
    if( pDispatcher )
    {
        pDispatcher->Execute( SID_BASICIDE_LIBSELECTED,
                              SFX_CALLMODE_SYNCHRON, &aLibName, 0L );
    }
*/
    ReleaseFocus();
}

<commit_msg>INTEGRATION: CWS tbe11 (1.3.70); FILE MERGED 2004/07/19 13:36:10 tbe 1.3.70.4: #i31315# Rework Basic IDE Macro Chooser and Macro Organizer 2004/07/16 13:28:18 tbe 1.3.70.3: RESYNC: (1.3-1.4); FILE MERGED 2004/07/09 15:53:12 tbe 1.3.70.2: #i31315# Rework Basic IDE Macro Chooser and Macro Organizer 2004/06/21 11:23:43 tbe 1.3.70.1: #99468# Basic IDE cannot handle libraries, which contain dialogs only<commit_after>/*************************************************************************
 *
 *  $RCSfile: basicbox.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2004-07-23 12:00:50 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <ide_pch.hxx>

#pragma hdrstop

#include <basidesh.hrc>
#include <basidesh.hxx>
#include <basobj.hxx>

#include <basicbox.hxx>
#include <iderid.hxx>
#include <iderdll.hxx>
#include <bastypes.hxx>

#ifndef _BASTYPE2_HXX
#include "bastype2.hxx"
#endif
#ifndef _BASDOC_HXX
#include "basdoc.hxx"
#endif

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

SFX_IMPL_TOOLBOX_CONTROL( LibBoxControl, SfxStringItem );

LibBoxControl::LibBoxControl( USHORT nSlotId, USHORT nId, ToolBox& rTbx )
    : SfxToolBoxControl( nSlotId, nId, rTbx )
{
}

LibBoxControl::~LibBoxControl()
{
}

void LibBoxControl::StateChanged( USHORT nSID, SfxItemState eState, const SfxPoolItem* pState )
{
    BasicLibBox* pBox = (BasicLibBox*) GetToolBox().GetItemWindow( GetId() );

    DBG_ASSERT( pBox, "Box not found" );
    if ( !pBox )
        return;

    if ( eState != SFX_ITEM_AVAILABLE )
        pBox->Disable();
    else
    {
        pBox->Enable();

        if ( pState->ISA(SfxStringItem) )
            pBox->Update( (const SfxStringItem*)pState );
        else
            pBox->Update( NULL );
    }
}

Window* LibBoxControl::CreateItemWindow( Window *pParent )
{
    return new BasicLibBox( pParent, m_xFrame );
}

BasicLibBox::BasicLibBox( Window* pParent, const uno::Reference< frame::XFrame >& rFrame ) :
    ListBox( pParent, WinBits( WB_BORDER | WB_DROPDOWN ) ),
    m_xFrame( rFrame )
{
    FillBox();
    bIgnoreSelect = TRUE;   // Select von 0 noch nicht weiterleiten
    bFillBox = TRUE;
    SelectEntryPos( 0 );
    aCurText = GetEntry( 0 );
    SetSizePixel( Size( 250, 200 ) );
    bIgnoreSelect = FALSE;
    StartListening( *SFX_APP(), TRUE /* Nur einmal anmelden */ );
}

__EXPORT BasicLibBox::~BasicLibBox()
{
}

void __EXPORT BasicLibBox::Update( const SfxStringItem* pItem )
{
    // Immer auf dem laufenden sein...
//  if ( !pItem  || !pItem->GetValue().Len() )
        FillBox();

    if ( pItem )
    {
        aCurText = pItem->GetValue();
        if ( aCurText.Len() == 0 )
            aCurText = String( IDEResId( RID_STR_ALL ) );
    }

    if ( GetSelectEntry() != aCurText )
        SelectEntry( aCurText );
}

void __EXPORT BasicLibBox::ReleaseFocus()
{
    SfxViewShell* pCurSh = SfxViewShell::Current();
    DBG_ASSERT( pCurSh, "Current ViewShell not found!" );

    if ( pCurSh )
    {
        Window* pShellWin = pCurSh->GetWindow();
        if ( !pShellWin )       // sonst werde ich ihn nicht los
            pShellWin = Application::GetDefDialogParent();

        pShellWin->GrabFocus();
    }
}

void __EXPORT BasicLibBox::SFX_NOTIFY(  SfxBroadcaster& rBC, const TypeId&,
                                        const SfxHint& rHint, const TypeId& )
{
    if ( rHint.IsA( TYPE( SfxEventHint ) ) )
    {
        if ( ( ((SfxEventHint&)rHint).GetEventId() == SFX_EVENT_CREATEDOC ) ||
             ( ((SfxEventHint&)rHint).GetEventId() == SFX_EVENT_OPENDOC ) )
        {
            FillBox();  // IDE reagiert selbst, wenn == aktuelle Lib
        }
        else if ( ((SfxEventHint&)rHint).GetEventId() == SFX_EVENT_SAVEASDOC )
        {
            FillBox( TRUE );
        }
        else if ( ((SfxEventHint&)rHint).GetEventId() == SFX_EVENT_CLOSEDOC )
        {
            if ( SFX_APP()->IsInBasicCall() )   // Nicht wenn Office beendet
                FillBox();
        }
    }
}

void BasicLibBox::FillBox( BOOL bSelect )
{
    SetUpdateMode( FALSE );
    bIgnoreSelect = TRUE;

    aCurText = GetSelectEntry();

    SelectEntryPos( 0 );
    Clear();

    // create list box entries
    USHORT nPos = InsertEntry( String( IDEResId( RID_STR_ALL ) ), LISTBOX_APPEND );
    SetEntryData( nPos, new BasicLibEntry( 0, LIBRARY_LOCATION_UNKNOWN, String() ) );
    InsertEntries( 0, LIBRARY_LOCATION_USER );
    InsertEntries( 0, LIBRARY_LOCATION_SHARE );
    SfxObjectShell* pShell = SfxObjectShell::GetFirst();
    while ( pShell )
    {
        // only if there's a corresponding window (not for remote documents)
        if ( SfxViewFrame::GetFirst( pShell ) && !pShell->ISA( BasicDocShell ) )
            InsertEntries( pShell, LIBRARY_LOCATION_DOCUMENT );

        pShell = SfxObjectShell::GetNext( *pShell );
    }

    SetUpdateMode( TRUE );

    if ( bSelect )
    {
        SelectEntry( aCurText );
        if ( !GetSelectEntryCount() )
        {
            SelectEntryPos( GetEntryCount() );  // gibst es nicht => leer?
            aCurText = GetSelectEntry();
        }
    }
    bIgnoreSelect = FALSE;
}

void BasicLibBox::InsertEntries( SfxObjectShell* pShell, LibraryLocation eLocation )
{
    // get a sorted list of library names
    Sequence< ::rtl::OUString > aLibNames = BasicIDE::GetLibraryNames( pShell );
    sal_Int32 nLibCount = aLibNames.getLength();
    const ::rtl::OUString* pLibNames = aLibNames.getConstArray();

    for ( sal_Int32 i = 0 ; i < nLibCount ; ++i )
    {
        String aLibName = pLibNames[ i ];
        if ( eLocation == BasicIDE::GetLibraryLocation( pShell, aLibName ) )
        {
            String aName( BasicIDE::GetTitle( pShell, eLocation, SFX_TITLE_FILENAME ) );
            String aEntryText( CreateMgrAndLibStr( aName, aLibName ) );
            USHORT nPos = InsertEntry( aEntryText, LISTBOX_APPEND );
            SetEntryData( nPos, new BasicLibEntry( pShell, eLocation, aLibName ) );
        }
    }
}

long BasicLibBox::PreNotify( NotifyEvent& rNEvt )
{
    long nDone = 0;
    if( rNEvt.GetType() == EVENT_KEYINPUT )
    {
        KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
        USHORT nKeyCode = aKeyEvt.GetKeyCode().GetCode();
        switch( nKeyCode )
        {
            case KEY_RETURN:
            {
                NotifyIDE();
                nDone = 1;
            }
            break;

            case KEY_ESCAPE:
            {
                SelectEntry( aCurText );
                ReleaseFocus();
                nDone = 1;
            }
            break;
        }
    }
    else if( rNEvt.GetType() == EVENT_GETFOCUS )
    {
        if ( bFillBox )
        {
            FillBox();
            bFillBox = FALSE;
        }
    }
    else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
    {
        if ( !HasChildPathFocus( TRUE ) )
        {
            bIgnoreSelect = TRUE;
            bFillBox = TRUE;
        }
    }

    return nDone ? nDone : ListBox::PreNotify( rNEvt );
}

void __EXPORT BasicLibBox::Select()
{
    if ( !IsTravelSelect() )
    {
        if ( !bIgnoreSelect )
            NotifyIDE();
        else
            SelectEntry( aCurText );    // Seit 306... (Select nach Escape)
    }
}

void BasicLibBox::NotifyIDE()
{
    USHORT nSelPos = GetSelectEntryPos();
    BasicLibEntry* pEntry = (BasicLibEntry*)GetEntryData( nSelPos );
    if ( pEntry )
    {
        SfxObjectShell* pShell = pEntry->GetShell();
        SfxObjectShellItem aShellItem( SID_BASICIDE_ARG_SHELL, pShell );
        String aLibName = pEntry->GetLibName();
        SfxStringItem aLibNameItem( SID_BASICIDE_ARG_LIBNAME, aLibName );
        BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
        SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
        SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;
        if ( pDispatcher )
        {
            pDispatcher->Execute( SID_BASICIDE_LIBSELECTED,
                                  SFX_CALLMODE_SYNCHRON, &aShellItem, &aLibNameItem, 0L );
        }
    }
    ReleaseFocus();
}
<|endoftext|>


<commit_before><commit_msg>fdo#57950: Remove chained append and simplify strings<commit_after><|endoftext|>