mirror of https://github.com/Icinga/icinga2.git
259 lines
7.5 KiB
C++
259 lines
7.5 KiB
C++
|
/******************************************************************************
|
||
|
* Icinga 2 *
|
||
|
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||
|
* *
|
||
|
* This program is free software; you can redistribute it and/or *
|
||
|
* modify it under the terms of the GNU General Public License *
|
||
|
* as published by the Free Software Foundation; either version 2 *
|
||
|
* of the License, or (at your option) any later version. *
|
||
|
* *
|
||
|
* 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 General Public License for more details. *
|
||
|
* *
|
||
|
* You should have received a copy of the GNU General Public License *
|
||
|
* along with this program; if not, write to the Free Software Foundation *
|
||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||
|
******************************************************************************/
|
||
|
|
||
|
#include "icinga-studio/mainform.hpp"
|
||
|
#include "icinga-studio/aboutform.hpp"
|
||
|
#include <boost/algorithm/string/split.hpp>
|
||
|
#include <boost/algorithm/string/classification.hpp>
|
||
|
#include <boost/foreach.hpp>
|
||
|
|
||
|
using namespace icinga;
|
||
|
|
||
|
MainForm::MainForm(wxWindow *parent, const Url::Ptr& url)
|
||
|
: MainFormBase(parent)
|
||
|
{
|
||
|
#ifdef _WIN32
|
||
|
SetIcon(wxICON(icinga));
|
||
|
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
|
||
|
#endif /* _WIN32 */
|
||
|
|
||
|
String host, port, user, pass;
|
||
|
|
||
|
std::string authority = url->GetAuthority();
|
||
|
|
||
|
std::vector<std::string> tokens;
|
||
|
boost::algorithm::split(tokens, authority, boost::is_any_of("@"));
|
||
|
|
||
|
if (tokens.size() > 1) {
|
||
|
std::vector<std::string> userinfo;
|
||
|
boost::algorithm::split(userinfo, tokens[0], boost::is_any_of(":"));
|
||
|
|
||
|
user = userinfo[0];
|
||
|
pass = userinfo[1];
|
||
|
}
|
||
|
|
||
|
std::vector<std::string> hostport;
|
||
|
boost::algorithm::split(hostport, tokens.size() > 1 ? tokens[1] : tokens[0], boost::is_any_of(":"));
|
||
|
|
||
|
host = hostport[0];
|
||
|
|
||
|
if (hostport.size() > 1)
|
||
|
port = hostport[1];
|
||
|
else
|
||
|
port = "5665";
|
||
|
|
||
|
m_ApiClient = new ApiClient(host, port, user, pass);
|
||
|
m_ApiClient->GetTypes(boost::bind(&MainForm::TypesCompletionHandler, this, _1, true));
|
||
|
|
||
|
std::string title = host;
|
||
|
|
||
|
if (port != "5665")
|
||
|
title += +":" + port;
|
||
|
|
||
|
title += " - Icinga Studio";
|
||
|
SetTitle(title);
|
||
|
|
||
|
m_ObjectsList->InsertColumn(0, "Name", 0, 300);
|
||
|
}
|
||
|
|
||
|
void MainForm::TypesCompletionHandler(const std::vector<ApiType::Ptr>& types, bool forward)
|
||
|
{
|
||
|
if (forward) {
|
||
|
CallAfter(boost::bind(&MainForm::TypesCompletionHandler, this, types, false));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
m_TypesTree->DeleteAllItems();
|
||
|
wxTreeItemId rootNode = m_TypesTree->AddRoot("root");
|
||
|
|
||
|
bool all = false;
|
||
|
std::map<String, wxTreeItemId> items;
|
||
|
|
||
|
m_Types.clear();
|
||
|
|
||
|
while (!all) {
|
||
|
all = true;
|
||
|
|
||
|
BOOST_FOREACH(const ApiType::Ptr& type, types) {
|
||
|
std::string name = type->Name;
|
||
|
|
||
|
if (items.find(name) != items.end())
|
||
|
continue;
|
||
|
|
||
|
all = false;
|
||
|
|
||
|
wxTreeItemId parent;
|
||
|
|
||
|
if (type->BaseName.IsEmpty())
|
||
|
parent = rootNode;
|
||
|
else {
|
||
|
std::map<String, wxTreeItemId>::const_iterator it = items.find(type->BaseName);
|
||
|
|
||
|
if (it == items.end())
|
||
|
continue;
|
||
|
|
||
|
parent = it->second;
|
||
|
}
|
||
|
|
||
|
m_Types[name] = type;
|
||
|
items[name] = m_TypesTree->AppendItem(parent, name, 0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MainForm::OnTypeSelected(wxTreeEvent& event)
|
||
|
{
|
||
|
wxTreeItemId selectedId = m_TypesTree->GetSelection();
|
||
|
wxString typeName = m_TypesTree->GetItemText(selectedId);
|
||
|
ApiType::Ptr type = m_Types[typeName.ToStdString()];
|
||
|
|
||
|
std::vector<String> attrs;
|
||
|
attrs.push_back(type->Name.ToLower() + ".__name");
|
||
|
|
||
|
m_ApiClient->GetObjects(type->PluralName, boost::bind(&MainForm::ObjectsCompletionHandler, this, _1, true),
|
||
|
std::vector<String>(), attrs);
|
||
|
}
|
||
|
|
||
|
void MainForm::ObjectsCompletionHandler(const std::vector<ApiObject::Ptr>& objects, bool forward)
|
||
|
{
|
||
|
if (forward) {
|
||
|
CallAfter(boost::bind(&MainForm::ObjectsCompletionHandler, this, objects, false));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
wxTreeItemId selectedId = m_TypesTree->GetSelection();
|
||
|
wxString typeName = m_TypesTree->GetItemText(selectedId);
|
||
|
ApiType::Ptr type = m_Types[typeName.ToStdString()];
|
||
|
|
||
|
String nameAttr = type->Name.ToLower() + ".__name";
|
||
|
|
||
|
m_ObjectsList->DeleteAllItems();
|
||
|
|
||
|
BOOST_FOREACH(const ApiObject::Ptr& object, objects) {
|
||
|
std::map<String, Value>::const_iterator it = object->Attrs.find(nameAttr);
|
||
|
if (it == object->Attrs.end())
|
||
|
continue;
|
||
|
String name = it->second;
|
||
|
m_ObjectsList->InsertItem(0, name.GetData());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MainForm::OnObjectSelected(wxListEvent& event)
|
||
|
{
|
||
|
wxTreeItemId selectedId = m_TypesTree->GetSelection();
|
||
|
wxString typeName = m_TypesTree->GetItemText(selectedId);
|
||
|
ApiType::Ptr type = m_Types[typeName.ToStdString()];
|
||
|
|
||
|
long itemIndex = -1;
|
||
|
std::string objectName;
|
||
|
|
||
|
while ((itemIndex = m_ObjectsList->GetNextItem(itemIndex,
|
||
|
wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED)) != wxNOT_FOUND) {
|
||
|
objectName = m_ObjectsList->GetItemText(itemIndex);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (objectName.empty())
|
||
|
return;
|
||
|
|
||
|
std::vector<String> names;
|
||
|
names.push_back(objectName);
|
||
|
|
||
|
m_ApiClient->GetObjects(type->PluralName, boost::bind(&MainForm::ObjectDetailsCompletionHandler, this, _1, true), names);
|
||
|
}
|
||
|
|
||
|
wxPGProperty *MainForm::ValueToProperty(const String& name, const Value& value)
|
||
|
{
|
||
|
wxPGProperty *prop;
|
||
|
|
||
|
if (value.IsNumber()) {
|
||
|
double val = value;
|
||
|
return new wxFloatProperty(name.GetData(), wxPG_LABEL, value);
|
||
|
} else if (value.IsBoolean()) {
|
||
|
bool val = value;
|
||
|
return new wxBoolProperty(name.GetData(), wxPG_LABEL, value);
|
||
|
} else if (value.IsObjectType<Array>()) {
|
||
|
wxArrayString val;
|
||
|
Array::Ptr arr = value;
|
||
|
ObjectLock olock(arr);
|
||
|
BOOST_FOREACH(const Value& aitem, arr)
|
||
|
{
|
||
|
String val1 = aitem;
|
||
|
val.Add(val1.GetData());
|
||
|
}
|
||
|
|
||
|
return new wxArrayStringProperty(name.GetData(), wxPG_LABEL, val);
|
||
|
} else if (value.IsObjectType<Dictionary>()) {
|
||
|
wxStringProperty *prop = new wxStringProperty(name.GetData(), wxPG_LABEL, "<dictionary>");
|
||
|
|
||
|
Dictionary::Ptr dict = value;
|
||
|
ObjectLock olock(dict);
|
||
|
BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
|
||
|
prop->AppendChild(ValueToProperty(kv.first, kv.second));
|
||
|
}
|
||
|
|
||
|
return prop;
|
||
|
} else {
|
||
|
String val = value;
|
||
|
return new wxStringProperty(name.GetData(), wxPG_LABEL, val.GetData());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MainForm::ObjectDetailsCompletionHandler(const std::vector<ApiObject::Ptr>& objects, bool forward)
|
||
|
{
|
||
|
if (forward) {
|
||
|
CallAfter(boost::bind(&MainForm::ObjectDetailsCompletionHandler, this, objects, false));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
wxTreeItemId selectedId = m_TypesTree->GetSelection();
|
||
|
wxString typeName = m_TypesTree->GetItemText(selectedId);
|
||
|
ApiType::Ptr type = m_Types[typeName.ToStdString()];
|
||
|
|
||
|
String nameAttr = type->Name.ToLower() + ".__name";
|
||
|
|
||
|
m_PropertyGrid->Clear();
|
||
|
|
||
|
if (objects.empty())
|
||
|
return;
|
||
|
|
||
|
ApiObject::Ptr object = objects[0];
|
||
|
|
||
|
typedef std::pair<String, Value> kv_pair;
|
||
|
BOOST_FOREACH(const kv_pair& kv, object->Attrs) {
|
||
|
std::vector<String> tokens;
|
||
|
boost::algorithm::split(tokens, kv.first, boost::is_any_of("."));
|
||
|
|
||
|
wxPGProperty *prop = ValueToProperty(tokens[1], kv.second);
|
||
|
m_PropertyGrid->Append(prop);
|
||
|
m_PropertyGrid->SetPropertyReadOnly(prop);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MainForm::OnQuitClicked(wxCommandEvent& event)
|
||
|
{
|
||
|
Close();
|
||
|
}
|
||
|
|
||
|
void MainForm::OnAboutClicked(wxCommandEvent& event)
|
||
|
{
|
||
|
AboutForm form(this);
|
||
|
form.ShowModal();
|
||
|
}
|