mirror of https://github.com/KLayout/klayout.git
WIP: more information on packages
This commit is contained in:
parent
3a6e4982c8
commit
3f9f06a9b9
|
|
@ -167,7 +167,7 @@
|
|||
</size>
|
||||
</property>
|
||||
<property name="selectionRectVisible">
|
||||
<bool>true</bool>
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QBuffer>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
|
@ -46,6 +47,9 @@ SaltGrain::operator== (const SaltGrain &other) const
|
|||
m_url == other.m_url &&
|
||||
m_title == other.m_title &&
|
||||
m_doc == other.m_doc &&
|
||||
m_doc_url == other.m_doc_url &&
|
||||
m_icon == other.m_icon &&
|
||||
m_screenshot == other.m_screenshot &&
|
||||
m_dependencies == other.m_dependencies &&
|
||||
m_author == other.m_author &&
|
||||
m_author_contact == other.m_author_contact &&
|
||||
|
|
@ -90,6 +94,12 @@ SaltGrain::set_doc (const std::string &t)
|
|||
m_doc = t;
|
||||
}
|
||||
|
||||
void
|
||||
SaltGrain::set_doc_url (const std::string &u)
|
||||
{
|
||||
m_doc_url = u;
|
||||
}
|
||||
|
||||
void
|
||||
SaltGrain::set_author (const std::string &a)
|
||||
{
|
||||
|
|
@ -120,6 +130,18 @@ SaltGrain::set_installed_time (const QDateTime &t)
|
|||
m_installed_time = t;
|
||||
}
|
||||
|
||||
void
|
||||
SaltGrain::set_screenshot (const QImage &i)
|
||||
{
|
||||
m_screenshot = i;
|
||||
}
|
||||
|
||||
void
|
||||
SaltGrain::set_icon (const QImage &i)
|
||||
{
|
||||
m_icon = i;
|
||||
}
|
||||
|
||||
int
|
||||
SaltGrain::compare_versions (const std::string &v1, const std::string &v2)
|
||||
{
|
||||
|
|
@ -184,17 +206,45 @@ struct TimeConverter
|
|||
}
|
||||
};
|
||||
|
||||
struct ImageConverter
|
||||
{
|
||||
std::string to_string (const QImage &image) const
|
||||
{
|
||||
if (image.isNull ()) {
|
||||
return std::string ();
|
||||
} else {
|
||||
QBuffer buffer;
|
||||
buffer.open (QIODevice::WriteOnly);
|
||||
image.save (&buffer, "PNG");
|
||||
buffer.close ();
|
||||
return buffer.buffer ().toBase64 ().constData ();
|
||||
}
|
||||
}
|
||||
|
||||
void from_string (const std::string &image, QImage &res) const
|
||||
{
|
||||
if (image.empty ()) {
|
||||
res = QImage ();
|
||||
} else {
|
||||
res = QImage::fromData (QByteArray::fromBase64 (QByteArray (image.c_str (), image.size ())));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static tl::XMLStruct<lay::SaltGrain> xml_struct ("salt-grain",
|
||||
tl::make_member (&SaltGrain::name, &SaltGrain::set_name, "name") +
|
||||
tl::make_member (&SaltGrain::version, &SaltGrain::set_version, "version") +
|
||||
tl::make_member (&SaltGrain::title, &SaltGrain::set_title, "title") +
|
||||
tl::make_member (&SaltGrain::doc, &SaltGrain::set_doc, "doc") +
|
||||
tl::make_member (&SaltGrain::doc_url, &SaltGrain::set_doc_url, "doc-url") +
|
||||
tl::make_member (&SaltGrain::url, &SaltGrain::set_url, "url") +
|
||||
tl::make_member (&SaltGrain::license, &SaltGrain::set_license, "license") +
|
||||
tl::make_member (&SaltGrain::author, &SaltGrain::set_author, "author") +
|
||||
tl::make_member (&SaltGrain::author_contact, &SaltGrain::set_author_contact, "author-contact") +
|
||||
tl::make_member (&SaltGrain::authored_time, &SaltGrain::set_authored_time, "authored-time", TimeConverter ()) +
|
||||
tl::make_member (&SaltGrain::installed_time, &SaltGrain::set_installed_time, "installed-time", TimeConverter ()) +
|
||||
tl::make_member (&SaltGrain::icon, &SaltGrain::set_icon, "icon", ImageConverter ()) +
|
||||
tl::make_member (&SaltGrain::screenshot, &SaltGrain::set_screenshot, "screenshot", ImageConverter ()) +
|
||||
tl::make_element (&SaltGrain::begin_dependencies, &SaltGrain::end_dependencies, &SaltGrain::add_dependency, "depends",
|
||||
tl::make_member (&SaltGrain::Dependency::name, "name") +
|
||||
tl::make_member (&SaltGrain::Dependency::url, "url") +
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "tlObject.h"
|
||||
|
||||
#include <QTime>
|
||||
#include <QImage>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
|
@ -115,8 +116,7 @@ public:
|
|||
/**
|
||||
* @brief Gets the documentation text of the grain
|
||||
*
|
||||
* The documentation text is an XML document using
|
||||
* KLayout's doc format.
|
||||
* The documentation text is a brief description.
|
||||
*/
|
||||
const std::string &doc () const
|
||||
{
|
||||
|
|
@ -128,6 +128,21 @@ public:
|
|||
*/
|
||||
void set_doc (const std::string &t);
|
||||
|
||||
/**
|
||||
* @brief Gets the documentation URL of the grain
|
||||
*
|
||||
* The documentation URL provides a detailed documentation.
|
||||
*/
|
||||
const std::string &doc_url () const
|
||||
{
|
||||
return m_doc_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the documentation URL of the grain
|
||||
*/
|
||||
void set_doc_url (const std::string &u);
|
||||
|
||||
/**
|
||||
* @brief Gets the version of the grain
|
||||
*
|
||||
|
|
@ -209,6 +224,35 @@ public:
|
|||
*/
|
||||
void set_installed_time (const QDateTime &t);
|
||||
|
||||
/**
|
||||
* @brief Gets the icon image for the grain.
|
||||
* The preferred image size is 64x64 pixels.
|
||||
* The image may be null image. In this case, a default image is used.
|
||||
*/
|
||||
const QImage &icon () const
|
||||
{
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets icon image
|
||||
*/
|
||||
void set_icon (const QImage &i);
|
||||
|
||||
/**
|
||||
* @brief Gets a screenshot image for documentation.
|
||||
* The image may be null image. In this case, no screenshot is shown.
|
||||
*/
|
||||
const QImage &screenshot () const
|
||||
{
|
||||
return m_screenshot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets screenshot image
|
||||
*/
|
||||
void set_screenshot (const QImage &i);
|
||||
|
||||
/**
|
||||
* @brief Gets the absolute file path of the installed grain
|
||||
* This is the file path to the grain folder.
|
||||
|
|
@ -327,11 +371,12 @@ private:
|
|||
std::string m_path;
|
||||
std::string m_url;
|
||||
std::string m_title;
|
||||
std::string m_doc;
|
||||
std::string m_doc, m_doc_url;
|
||||
std::string m_author;
|
||||
std::string m_author_contact;
|
||||
std::string m_license;
|
||||
QDateTime m_authored_time, m_installed_time;
|
||||
QImage m_icon, m_screenshot;
|
||||
std::vector<Dependency> m_dependencies;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <QTextStream>
|
||||
#include <QBuffer>
|
||||
#include <QIcon>
|
||||
#include <QPainter>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
|
@ -49,9 +50,54 @@ QVariant
|
|||
SaltGrainDetailsTextWidget::loadResource (int type, const QUrl &url)
|
||||
{
|
||||
if (url.path () == QString::fromUtf8 ("/icon")) {
|
||||
// @@@
|
||||
return QImage (":/salt_icon.png");
|
||||
// @@@
|
||||
|
||||
if (!mp_grain || mp_grain->icon ().isNull ()) {
|
||||
return QImage (":/salt_icon.png");
|
||||
} else {
|
||||
QImage img = mp_grain->icon ();
|
||||
if (img.width () != 64) {
|
||||
return img.scaled (QSize (64, 64), Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
||||
} else {
|
||||
return img;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (url.path () == QString::fromUtf8 ("/screenshot")) {
|
||||
|
||||
QImage s = mp_grain->screenshot ().convertToFormat (QImage::Format_ARGB32_Premultiplied);
|
||||
|
||||
QImage smask (s.size (), QImage::Format_ARGB32_Premultiplied);
|
||||
smask.fill (QColor (0, 0, 0, 0));
|
||||
{
|
||||
int border = 4;
|
||||
int radius = 6;
|
||||
|
||||
QPainter painter (&smask);
|
||||
|
||||
painter.setRenderHint (QPainter::Antialiasing);
|
||||
|
||||
painter.setCompositionMode (QPainter::CompositionMode_Source);
|
||||
for (int b = border; b > 0; --b) {
|
||||
QPen pen (QColor (255, 255, 255, ((border - b + 1) * 255) / border));
|
||||
pen.setWidth (b * 2 + 1);
|
||||
painter.setBrush (Qt::NoBrush);
|
||||
painter.setPen (pen);
|
||||
painter.drawRoundedRect (QRectF (border, border, s.width () - 2 * border, s.height () - 2 * border), radius, radius, Qt::AbsoluteSize);
|
||||
}
|
||||
|
||||
painter.setPen (Qt::white);
|
||||
painter.setBrush (Qt::white);
|
||||
painter.drawRoundedRect (QRectF (border, border, s.width () - 2 * border, s.height () - 2 * border), radius, radius, Qt::AbsoluteSize);
|
||||
}
|
||||
|
||||
{
|
||||
QPainter painter (&s);
|
||||
painter.setCompositionMode (QPainter::CompositionMode_DestinationIn);
|
||||
painter.drawImage (0, 0, smask);
|
||||
}
|
||||
|
||||
return s;
|
||||
|
||||
} else {
|
||||
return QTextBrowser::loadResource (type, url);
|
||||
}
|
||||
|
|
@ -72,8 +118,9 @@ SaltGrainDetailsTextWidget::details_text ()
|
|||
|
||||
stream << "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/></head><body>";
|
||||
|
||||
stream << "<table><tr>";
|
||||
stream << "<td><img src=\":/icon\"/></td>";
|
||||
stream << "<table cellpadding=\"6\"><tr>";
|
||||
stream << "<td><img src=\":/icon\" width=\"64\" height=\"64\"/></td>";
|
||||
|
||||
stream << "<td>";
|
||||
stream << "<h1>";
|
||||
stream << tl::to_qstring (tl::escaped_to_html (g->name ())) << " " << tl::to_qstring (tl::escaped_to_html (g->version ()));
|
||||
|
|
@ -96,8 +143,6 @@ SaltGrainDetailsTextWidget::details_text ()
|
|||
stream << "</font></i></p>";
|
||||
}
|
||||
|
||||
stream << "</td></tr></table>";
|
||||
|
||||
stream << "<p><br/>";
|
||||
if (! g->doc ().empty ()) {
|
||||
stream << tl::to_qstring (tl::escaped_to_html (g->doc ()));
|
||||
|
|
@ -128,16 +173,52 @@ SaltGrainDetailsTextWidget::details_text ()
|
|||
stream << "</p>";
|
||||
|
||||
stream << "<p>";
|
||||
if (! g->url ().empty ()) {
|
||||
stream << "<b>" << QObject::tr ("Documentation link") << ":</b> <a href=\"" << tl::to_qstring (g->url ()) << "\">" << tl::to_qstring (tl::escaped_to_html (g->url ())) << "</a>";
|
||||
if (! g->license ().empty ()) {
|
||||
stream << "<b>" << QObject::tr ("License") << ":</b> " << tl::to_qstring (tl::escaped_to_html (g->license ())) << " ";
|
||||
} else {
|
||||
stream << "<i><font color='gray'>";
|
||||
stream << QObject::tr ("This package does not have a documentation link. "
|
||||
"Use the <url> element of the specification file or edit the package properties to provide a link.");
|
||||
stream << QObject::tr ("This package does not have license information. "
|
||||
"Use the <license> elements of the specification file or edit the package properties to provide license information.");
|
||||
stream << "</font></i>";
|
||||
}
|
||||
stream << "</p>";
|
||||
|
||||
stream << "<p>";
|
||||
if (! g->doc_url ().empty ()) {
|
||||
stream << "<b>" << QObject::tr ("Documentation link") << ":</b> <a href=\"" << tl::to_qstring (g->doc_url ()) << "\">" << tl::to_qstring (tl::escaped_to_html (g->doc_url ())) << "</a>";
|
||||
} else {
|
||||
stream << "<i><font color='gray'>";
|
||||
stream << QObject::tr ("This package does not have a documentation link. "
|
||||
"Use the <doc-url> element of the specification file or edit the package properties to provide a link.");
|
||||
stream << "</font></i>";
|
||||
}
|
||||
stream << "</p>";
|
||||
|
||||
if (! g->screenshot ().isNull ()) {
|
||||
stream << "<br/>";
|
||||
stream << "<h3>" << QObject::tr ("Screenshot") << "</h3><p><img src=\":/screenshot\"/></p>";
|
||||
}
|
||||
|
||||
stream << "<br/>";
|
||||
stream << "<h3>" << QObject::tr ("Installation") << "</h3>";
|
||||
|
||||
stream << "<p><b>" << QObject::tr ("Installation path: ") << "</b>" << tl::to_qstring (tl::escaped_to_html (g->path ())) << "</p>";
|
||||
if (! g->url ().empty ()) {
|
||||
stream << "<p><b>" << QObject::tr ("Download URL: ") << "</b>" << tl::to_qstring (tl::escaped_to_html (g->url ())) << "</p>";
|
||||
}
|
||||
if (! g->installed_time ().isNull ()) {
|
||||
stream << "<p><b>" << QObject::tr ("Installed: ") << "</b>" << g->installed_time ().toString () << "</p>";
|
||||
}
|
||||
if (! g->dependencies ().empty ()) {
|
||||
stream << "<p><b>" << QObject::tr ("Depends on: ") << "</b></p><p>";
|
||||
for (std::vector<lay::SaltGrain::Dependency>::const_iterator d = g->dependencies ().begin (); d != g->dependencies ().end (); ++d) {
|
||||
stream << " " << tl::to_qstring (tl::escaped_to_html (d->name)) << " " << tl::to_qstring (tl::escaped_to_html (d->url)) << "<br/>";
|
||||
}
|
||||
stream << "</p>";
|
||||
}
|
||||
|
||||
stream << "</td></tr></table>";
|
||||
|
||||
stream << "</body></html>";
|
||||
|
||||
stream.flush ();
|
||||
|
|
|
|||
|
|
@ -80,9 +80,17 @@ public:
|
|||
|
||||
} else if (role == Qt::DecorationRole) {
|
||||
|
||||
// @@@
|
||||
return QIcon (":/salt_icon.png");
|
||||
// @@@
|
||||
const lay::SaltGrain *g = mp_salt->begin_flat ()[index.row ()];
|
||||
if (g->icon ().isNull ()) {
|
||||
return QIcon (":/salt_icon.png");
|
||||
} else {
|
||||
QPixmap px = QPixmap::fromImage (g->icon ());
|
||||
if (px.width () == 64) {
|
||||
return px;
|
||||
} else {
|
||||
return px.scaled (QSize (64, 64), Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
return QVariant ();
|
||||
|
|
|
|||
|
|
@ -99,6 +99,8 @@ TEST (1)
|
|||
EXPECT_EQ (g.title (), "title");
|
||||
g.set_doc ("doc");
|
||||
EXPECT_EQ (g.doc (), "doc");
|
||||
g.set_doc_url ("doc-url");
|
||||
EXPECT_EQ (g.doc_url (), "doc-url");
|
||||
g.set_author ("me");
|
||||
EXPECT_EQ (g.author (), "me");
|
||||
g.set_author_contact ("ac");
|
||||
|
|
|
|||
Loading…
Reference in New Issue