namespace lay
{
// --------------------------------------------------------------------------------------
-/**
- * @brief A model representing the salt grains for a QListView
- */
-class SaltModel
- : public QAbstractItemModel
-{
-public:
- SaltModel (QObject *parent, lay::Salt *salt)
- : QAbstractItemModel (parent), mp_salt (salt)
- {
- // .. nothing yet ..
- }
-
- QVariant data (const QModelIndex &index, int role) const
- {
- if (role == Qt::DisplayRole) {
-
- const lay::SaltGrain *g = mp_salt->begin_flat ()[index.row ()];
-
- std::string text = "";
- text += "";
- text += tl::escaped_to_html (g->name ());
- if (!g->version ().empty ()) {
- text += " ";
- text += tl::escaped_to_html (g->version ());
- }
- if (!g->title ().empty ()) {
- text += " - ";
- text += tl::escaped_to_html (g->title ());
- }
- text += "
";
- if (!g->doc ().empty ()) {
- text += "";
- text += tl::escaped_to_html (g->doc ());
- text += "
";
- }
- text += "";
-
- return tl::to_qstring (text);
-
- } else if (role == Qt::DecorationRole) {
-
- int icon_dim = 64;
-
- const lay::SaltGrain *g = mp_salt->begin_flat ()[index.row ()];
- if (g->icon ().isNull ()) {
- return QIcon (":/salt_icon.png");
- } else {
-
- QImage img = g->icon ();
- if (img.width () == icon_dim && img.height () == icon_dim) {
- return QPixmap::fromImage (img);
- } else {
-
- img = img.scaled (QSize (icon_dim, icon_dim), Qt::KeepAspectRatio, Qt::SmoothTransformation);
-
- QImage final_img (icon_dim, icon_dim, QImage::Format_ARGB32);
- final_img.fill (QColor (0, 0, 0, 0));
- QPainter painter (&final_img);
- painter.drawImage ((icon_dim - img.width ()) / 2, (icon_dim - img.height ()) / 2, img);
-
- return QPixmap::fromImage (final_img);
-
- }
-
- }
-
- } else {
- return QVariant ();
- }
- }
-
- QModelIndex index (int row, int column, const QModelIndex &parent) const
- {
- if (parent.isValid ()) {
- return QModelIndex ();
- } else {
- return createIndex (row, column, mp_salt->begin_flat () [row]);
- }
- }
-
- QModelIndex parent (const QModelIndex & /*index*/) const
- {
- return QModelIndex ();
- }
-
- int columnCount(const QModelIndex & /*parent*/) const
- {
- return 1;
- }
-
- int rowCount (const QModelIndex &parent) const
- {
- if (parent.isValid ()) {
- return 0;
- } else {
- return mp_salt->end_flat () - mp_salt->begin_flat ();
- }
- }
-
- SaltGrain *grain_from_index (const QModelIndex &index) const
- {
- if (index.isValid ()) {
- return static_cast (index.internalPointer ());
- } else {
- return 0;
- }
- }
-
- void update ()
- {
- reset ();
- }
-
-public:
- lay::Salt *mp_salt;
-};
-
-// --------------------------------------------------------------------------------------
-
-/**
- * @brief A delegate displaying the summary of a grain
- */
-class SaltItemDelegate
- : public QStyledItemDelegate
-{
-public:
- SaltItemDelegate (QObject *parent)
- : QStyledItemDelegate (parent)
- {
- // .. nothing yet ..
- }
-
- void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
- {
- QStyleOptionViewItemV4 optionV4 = option;
- initStyleOption (&optionV4, index);
-
- QStyle *style = optionV4.widget ? optionV4.widget->style () : QApplication::style ();
-
- QTextDocument doc;
- doc.setHtml (optionV4.text);
-
- optionV4.text = QString ();
- style->drawControl (QStyle::CE_ItemViewItem, &optionV4, painter);
-
- QAbstractTextDocumentLayout::PaintContext ctx;
-
- if (optionV4.state & QStyle::State_Selected) {
- ctx.palette.setColor (QPalette::Text, optionV4.palette.color (QPalette::Active, QPalette::HighlightedText));
- }
-
- QRect textRect = style->subElementRect (QStyle::SE_ItemViewItemText, &optionV4);
- painter->save ();
- painter->translate (textRect.topLeft ());
- painter->setClipRect (textRect.translated (-textRect.topLeft ()));
- doc.documentLayout()->draw (painter, ctx);
- painter->restore ();
- }
-
- QSize sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const
- {
- const int textWidth = 500;
-
- QStyleOptionViewItemV4 optionV4 = option;
- initStyleOption (&optionV4, index);
-
- const QListView *view = dynamic_cast (optionV4.widget);
- QSize icon_size (0, 0);
- if (view) {
- icon_size = view->iconSize ();
- }
-
- QTextDocument doc;
- doc.setHtml (optionV4.text);
- doc.setTextWidth (textWidth);
- return QSize (textWidth + icon_size.width () + 6, std::max (icon_size.height () + 12, int (doc.size ().height ())));
- }
-};
-
-// --------------------------------------------------------------------------------------
-
/**
* @brief A tiny dialog to select a template and a name for the grain
*/
@@ -384,17 +204,30 @@ END_PROTECTED
void
SaltManagerDialog::delete_grain ()
{
+BEGIN_PROTECTED
- // @@@
+ SaltGrain *g = current_grain ();
+ if (! g) {
+ throw tl::Exception (tl::to_string (tr ("No package selected to delete")));
+ }
+ if (QMessageBox::question (this, tr ("Delete Package"), tr ("Are you sure to delete package '%1'?").arg (tl::to_qstring (g->name ())), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
+ mp_salt->remove_grain (*g);
+ }
+
+END_PROTECTED
}
void
SaltManagerDialog::install_grain ()
{
+BEGIN_PROTECTED
- // @@@
+ // @@@ TODO: cache this somewhere - don't recreate this dialog always
+ SaltGrainInstallationDialog inst_dialog (this, mp_salt);
+ inst_dialog.exec ();
+END_PROTECTED
}
void
@@ -405,6 +238,8 @@ SaltManagerDialog::salt_changed ()
return;
}
+ // NOTE: the disabling of the event handler prevents us from
+ // letting the model connect to the salt's signal directly.
m_current_changed_enabled = false;
model->update ();
m_current_changed_enabled = true;
diff --git a/src/lay/laySaltModel.cc b/src/lay/laySaltModel.cc
new file mode 100644
index 000000000..ded796c86
--- /dev/null
+++ b/src/lay/laySaltModel.cc
@@ -0,0 +1,207 @@
+
+/*
+
+ KLayout Layout Viewer
+ Copyright (C) 2006-2017 Matthias Koefferlein
+
+ 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 "laySaltModel.h"
+#include "laySalt.h"
+
+#include
+#include
+#include
+#include
+#include
+
+namespace lay
+{
+
+// --------------------------------------------------------------------------------------
+
+SaltItemDelegate::SaltItemDelegate (QObject *parent)
+ : QStyledItemDelegate (parent)
+{
+ // .. nothing yet ..
+}
+
+void
+SaltItemDelegate::paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ QStyleOptionViewItemV4 optionV4 = option;
+ initStyleOption (&optionV4, index);
+
+ QStyle *style = optionV4.widget ? optionV4.widget->style () : QApplication::style ();
+
+ QTextDocument doc;
+ doc.setHtml (optionV4.text);
+
+ optionV4.text = QString ();
+ style->drawControl (QStyle::CE_ItemViewItem, &optionV4, painter);
+
+ QAbstractTextDocumentLayout::PaintContext ctx;
+
+ if (optionV4.state & QStyle::State_Selected) {
+ ctx.palette.setColor (QPalette::Text, optionV4.palette.color (QPalette::Active, QPalette::HighlightedText));
+ }
+
+ QRect textRect = style->subElementRect (QStyle::SE_ItemViewItemText, &optionV4);
+ painter->save ();
+ painter->translate (textRect.topLeft ());
+ painter->setClipRect (textRect.translated (-textRect.topLeft ()));
+ doc.documentLayout()->draw (painter, ctx);
+ painter->restore ();
+}
+
+QSize
+SaltItemDelegate::sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ const int textWidth = 500;
+
+ QStyleOptionViewItemV4 optionV4 = option;
+ initStyleOption (&optionV4, index);
+
+ const QListView *view = dynamic_cast (optionV4.widget);
+ QSize icon_size (0, 0);
+ if (view) {
+ icon_size = view->iconSize ();
+ }
+
+ QTextDocument doc;
+ doc.setHtml (optionV4.text);
+ doc.setTextWidth (textWidth);
+ return QSize (textWidth + icon_size.width () + 6, std::max (icon_size.height () + 12, int (doc.size ().height ())));
+}
+
+// --------------------------------------------------------------------------------------
+
+SaltModel::SaltModel (QObject *parent, lay::Salt *salt)
+ : QAbstractItemModel (parent), mp_salt (salt)
+{
+ // .. nothing yet ..
+}
+
+QVariant
+SaltModel::data (const QModelIndex &index, int role) const
+{
+ if (role == Qt::DisplayRole) {
+
+ const lay::SaltGrain *g = mp_salt->begin_flat ()[index.row ()];
+
+ std::string text = "";
+ text += "";
+ text += tl::escaped_to_html (g->name ());
+ if (!g->version ().empty ()) {
+ text += " ";
+ text += tl::escaped_to_html (g->version ());
+ }
+ if (!g->title ().empty ()) {
+ text += " - ";
+ text += tl::escaped_to_html (g->title ());
+ }
+ text += "
";
+ if (!g->doc ().empty ()) {
+ text += "";
+ text += tl::escaped_to_html (g->doc ());
+ text += "
";
+ }
+ text += "";
+
+ return tl::to_qstring (text);
+
+ } else if (role == Qt::DecorationRole) {
+
+ int icon_dim = 64;
+
+ const lay::SaltGrain *g = mp_salt->begin_flat ()[index.row ()];
+ if (g->icon ().isNull ()) {
+ return QIcon (":/salt_icon.png");
+ } else {
+
+ QImage img = g->icon ();
+ if (img.width () == icon_dim && img.height () == icon_dim) {
+ return QPixmap::fromImage (img);
+ } else {
+
+ img = img.scaled (QSize (icon_dim, icon_dim), Qt::KeepAspectRatio, Qt::SmoothTransformation);
+
+ QImage final_img (icon_dim, icon_dim, QImage::Format_ARGB32);
+ final_img.fill (QColor (0, 0, 0, 0));
+ QPainter painter (&final_img);
+ painter.drawImage ((icon_dim - img.width ()) / 2, (icon_dim - img.height ()) / 2, img);
+
+ return QPixmap::fromImage (final_img);
+
+ }
+
+ }
+
+ } else {
+ return QVariant ();
+ }
+}
+
+QModelIndex
+SaltModel::index (int row, int column, const QModelIndex &parent) const
+{
+ if (parent.isValid ()) {
+ return QModelIndex ();
+ } else {
+ return createIndex (row, column, mp_salt->begin_flat () [row]);
+ }
+}
+
+QModelIndex
+SaltModel::parent (const QModelIndex & /*index*/) const
+{
+ return QModelIndex ();
+}
+
+int
+SaltModel::columnCount(const QModelIndex & /*parent*/) const
+{
+ return 1;
+}
+
+int
+SaltModel::rowCount (const QModelIndex &parent) const
+{
+ if (parent.isValid ()) {
+ return 0;
+ } else {
+ return mp_salt->end_flat () - mp_salt->begin_flat ();
+ }
+}
+
+SaltGrain *
+SaltModel::grain_from_index (const QModelIndex &index) const
+{
+ if (index.isValid ()) {
+ return static_cast (index.internalPointer ());
+ } else {
+ return 0;
+ }
+}
+
+void
+SaltModel::update ()
+{
+ reset ();
+}
+
+}
diff --git a/src/lay/laySaltModel.h b/src/lay/laySaltModel.h
new file mode 100644
index 000000000..1ffa5f86e
--- /dev/null
+++ b/src/lay/laySaltModel.h
@@ -0,0 +1,110 @@
+
+/*
+
+ KLayout Layout Viewer
+ Copyright (C) 2006-2017 Matthias Koefferlein
+
+ 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
+
+*/
+
+#ifndef HDR_laySaltModel
+#define HDR_laySaltModel
+
+#include "layCommon.h"
+
+#include
+#include
+#include
+#include
+
+namespace lay
+{
+
+class Salt;
+class SaltGrain;
+
+/**
+ * @brief A model representing the salt grains for a QListView
+ */
+class SaltModel
+ : public QAbstractItemModel
+{
+Q_OBJECT
+
+public:
+ /**
+ * @brief Constructor
+ */
+ SaltModel (QObject *parent, lay::Salt *salt);
+
+ /**
+ * @brief Implementation of the QAbstractItemModel interface
+ */
+ QVariant data (const QModelIndex &index, int role) const;
+
+ /**
+ * @brief Implementation of the QAbstractItemModel interface
+ */
+ QModelIndex index (int row, int column, const QModelIndex &parent) const;
+
+ /**
+ * @brief Implementation of the QAbstractItemModel interface
+ */
+ QModelIndex parent (const QModelIndex & /*index*/) const;
+
+ /**
+ * @brief Implementation of the QAbstractItemModel interface
+ */
+ int columnCount(const QModelIndex & /*parent*/) const;
+
+ /**
+ * @brief Implementation of the QAbstractItemModel interface
+ */
+ int rowCount (const QModelIndex &parent) const;
+
+ /**
+ * @brief Gets the grain pointer from a model index
+ */
+ SaltGrain *grain_from_index (const QModelIndex &index) const;
+
+ /**
+ * @brief Updates the model
+ * Needs to be called when the salt has changed.
+ */
+ void update ();
+
+public:
+ lay::Salt *mp_salt;
+};
+
+// --------------------------------------------------------------------------------------
+
+/**
+ * @brief A delegate displaying the summary of a grain
+ */
+class SaltItemDelegate
+ : public QStyledItemDelegate
+{
+public:
+ SaltItemDelegate (QObject *parent);
+
+ void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+ QSize sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const;
+};
+
+}
+
+#endif
diff --git a/src/unit_tests/laySalt.cc b/src/unit_tests/laySalt.cc
index 9d3ef0a36..8edff9a14 100644
--- a/src/unit_tests/laySalt.cc
+++ b/src/unit_tests/laySalt.cc
@@ -240,6 +240,15 @@ TEST (3)
EXPECT_EQ (grains_to_string (gg), "[a,b,c[c/u,c/c[c/c/v]]]");
EXPECT_EQ (gg.begin_collections ()->path (), tl::to_string (dir_c.absolutePath ()));
+ std::string gg_path = tmp_file ("gg.tmp");
+ gg.save (gg_path);
+
+ lay::SaltGrains ggg;
+ ggg.load (gg_path);
+ EXPECT_EQ (grains_to_string (ggg), "[a,b,c[c/u,c/c[c/c/v]]]");
+ // NOTE: The path is not set, so this will fail:
+ // EXPECT_EQ (gg == ggg, true);
+
gg.remove_grain (gg.begin_grains (), false);
EXPECT_EQ (grains_to_string (gg), "[b,c[c/u,c/c[c/c/v]]]");