Aegisub/aegisub/reporter/report.cpp
Amar Takhar 930f593d6a dd the beginings of the Aegisub Reporter, this is my first C++ program from scratch. (yes, that's a disclaimer)
What's left to be done:
  * Crash support. (only works for 'reports')
  * UI cleanups.
  * Interfacing with Aegisub to get proper metrics.
  * OSX support.
  * Windows support. (someone else will have to do this)
  * Server-side code.

There's probably a lot of other things I'm forgetting, anyone is free to commit to this, if you want to make major changes let me know beforehand.

Originally committed to SVN as r3475.
2009-09-03 06:53:55 +00:00

206 lines
7.3 KiB
C++

// Copyright (c) 2009, Amar Takhar <verm@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// $Id$
/// @@file report.cpp
/// @brief Generation and manipulation of reports.
#ifndef R_PRECOMP
#include <wx/intl.h>
#endif
#include "report.h"
#include "platform.h"
#include "aegisub.h"
/// @brief Contstructor
Report::Report() {
ReportCreate();
}
/// @brief Create report layout and add contents.
/// @return Document.
Report::XMLReport Report::ReportCreate() {
// So we can use GetString() below.
locale = new wxLocale();
doc.doc = new wxXmlDocument();
doc.report = new wxXmlNode(wxXML_ELEMENT_NODE, "report");
doc.doc->SetRoot(doc.report);
Platform *p = Platform::GetPlatform();
doc.general = new wxXmlNode(doc.report, wxXML_ELEMENT_NODE, "general");
Add(doc.general, "signature", p->Signature());
Add(doc.general, "date", p->Date());
Add(doc.general, "arch", p->ArchName());
Add(doc.general, "osfamily", p->OSFamily());
Add(doc.general, "osname", p->OSName());
Add(doc.general, "osendian", p->Endian());
Add(doc.general, "osversion", p->OSVersion());
Add(doc.general, "wxversion", p->wxVersion());
Add(doc.general, "locale", p->Locale());
Add(doc.general, "lang", p->Language());
Add(doc.general, "syslang", p->SystemLanguage());
doc.aegisub = new wxXmlNode(wxXML_ELEMENT_NODE, "aegisub");
doc.report->AddChild(doc.aegisub);
Aegisub *config = new Aegisub::Aegisub();
Add(doc.aegisub, "lastversion", config->Read("Config/last version"));
Add(doc.aegisub, "spelllang", config->Read("Config/spell checker language"));
Add(doc.aegisub, "thesauruslang", config->Read("Config/thesaurus language"));
Add(doc.aegisub, "audioplayer", config->Read("Config/audio player"));
Add(doc.aegisub, "audioprovider", config->Read("Config/audio provider"));
Add(doc.aegisub, "videoprovider", config->Read("Config/video provider"));
Add(doc.aegisub, "subtitleprovider", config->Read("Config/subtitles provider"));
Add(doc.aegisub, "savecharset", config->Read("Config/save charset"));
Add(doc.aegisub, "gridfontsize", config->Read("Config/grid font size"));
Add(doc.aegisub, "editfontsize", config->Read("Config/edit font size"));
Add(doc.aegisub, "spectrum", config->Read("Config/audio spectrum"));
Add(doc.aegisub, "spectrumqual", config->Read("Config/audio spectrum quality"));
Add(doc.aegisub, "calltips", config->Read("Config/call tips enabled"));
Add(doc.aegisub, "medusakeys", config->Read("Config/audio medusa timing hotkeys"));
doc.hardware = new wxXmlNode(wxXML_ELEMENT_NODE, "hardware");
doc.report->AddChild(doc.hardware);
Add(doc.hardware, "memory", p->Memory());
Add(doc.hardware, "video", p->Video());
wxXmlNode *cpu = new wxXmlNode(wxXML_ELEMENT_NODE, "cpu");
doc.hardware->AddChild(cpu);
Add(cpu, "id", p->CPUId());
Add(cpu, "speed", p->CPUSpeed());
Add(cpu, "count", p->CPUCount());
Add(cpu, "cores", p->CPUCores());
Add(cpu, "features", p->CPUFeatures());
Add(cpu, "features2", p->CPUFeatures2());
wxXmlNode *display = new wxXmlNode(wxXML_ELEMENT_NODE, "display");
doc.hardware->AddChild(display);
Add(display, "depth", p->DisplayDepth());
Add(display, "colour", p->DisplayColour());
Add(display, "size", p->DisplaySize());
Add(display, "ppi", p->DisplayPPI());
#ifdef __WINDOWS__
doc.windows = new wxXmlNode(wxXML_ELEMENT_NODE, "windows");
doc.report->AddChild(doc.windows);
Add(doc.windows, "sp", p->ServicePack());
Add(doc.windows, "graphicsver", p->DriverGraphicsVersion());
Add(doc.windows, "dshowfilter", p->DirectShowFilters());
Add(doc.windows, "antivirus", p->());
Add(doc.windows, "firewall", p->());
Add(doc.windows, "dll", p->DLLVersions());
#endif
#ifdef __UNIX__
doc.unixx = new wxXmlNode(wxXML_ELEMENT_NODE, "unix");
doc.report->AddChild(doc.unixx);
Add(doc.unixx, "desktopenv", p->DesktopEnvironment());
Add(doc.unixx, "lib", p->UnixLibraries());
#endif
#ifdef __APPLE__
doc.osx = new wxXmlNode(wxXML_ELEMENT_NODE, "osx");
doc.report->AddChild(doc.osx);
Add(doc.osx, "patch", p->PatchLevel);
Add(doc.osx, "quicktimeext", p->QuickTimeExt);
Add(doc.osx, "model", p->HardwareModel);
#endif
return doc;
}
/// @brief Add a new XML node.
/// @param parent Parent nodee
/// @param node Name of the new node
/// @param text Contents
void Report::Add(wxXmlNode *parent, wxString node, wxString text) {
// Using AddChild() keeps the nodes in their natural order. It's slower but our
// document is pretty small. Doing it the faster way results in reverse-ordered nodes.
wxXmlNode *tmp = new wxXmlNode(wxXML_ELEMENT_NODE, node);
tmp->AddChild(new wxXmlNode(wxXML_TEXT_NODE, node, text));
parent->AddChild(tmp);
}
/// @brief Recursive function to populate listView and text-based for Clipboard.
/// @param node Node to parse.
/// @param listView wxListView to populate.
void Report::ProcessNode(wxXmlNode *node, wxString *text, wxListView *listView) {
wxString node_name;
nameMap::iterator names;
nameMap nMap = HumanNames();
wxXmlNode *child = node->GetChildren();
while (child) {
wxString name = child->GetName();
if ((names = nMap.find(std::string(name.utf8_str()))) != nMap.end()) {
node_name = locale->GetString(names->second);
} else {
wxLogDebug("Report::ProcessNode Unknown node found: \"%s\" (add it to nMap)\n", name);
node_name = name;
}
wxListItem column;
int row = listView->GetItemCount();
int depth = child->GetDepth();
if (child->GetChildren()->GetType() == wxXML_ELEMENT_NODE) {
int font_size = 15 - (round(depth * 2.5));
int bgcolour = 185 + (depth * 25);
listView->InsertItem(row,node_name);
listView->SetItemFont(row, wxFont(font_size, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD));
listView->SetItemBackgroundColour(row, wxColour(bgcolour,bgcolour,bgcolour, wxALPHA_OPAQUE));
if (depth == 1) text->Append("\n");
text->Append(wxString::Format("%s\n", node_name.Pad((depth*2)-2, ' ', 0)));
ProcessNode(child, text, listView);
} else {
wxString content = child->GetNodeContent();
listView->InsertItem(row,node_name);
listView->SetItem(row,1, content);
text->Append(wxString::Format("%-22s: %s\n", node_name.Pad((depth*2)-2, ' ', 0), content));
}
child = child->GetNext();
}
}
/// @brief Fill wxListView with report contents.
/// @param listview wxListview to fill.
void Report::Fill(wxString *text, wxListView *listView) {
listView->InsertColumn(0, _("Entry"), wxLIST_FORMAT_RIGHT);
listView->InsertColumn(1, _("Text"), wxLIST_FORMAT_LEFT, 100);
//wxString *text = new wxString();
ProcessNode(doc.report, text, listView);
listView->SetColumnWidth(0, wxLIST_AUTOSIZE);
listView->SetColumnWidth(1, wxLIST_AUTOSIZE);
}
/// @brief Return Report as Text for the Clipboard.
wxString Report::AsText() {
return "not implimented.";
}