Further reducing dependency on Qt, fixed tests

This commit is contained in:
Matthias Koefferlein 2022-05-29 10:11:16 +02:00
parent 1edaf2b6b4
commit 29b3718b2d
13 changed files with 173 additions and 92 deletions

View File

@ -28,9 +28,8 @@
#include "rba.h"
#include "gsiDecl.h"
// On Windows, ruby.h is not compatible with windows.h which is included by utHead - at least not if
// windows.h is included before ruby.h ...
#include "tlUnitTest.h"
#include "tlFileUtils.h"
void run_rubytest (tl::TestBase * /*_this*/, const std::string &fn)
{

View File

@ -2001,9 +2001,10 @@ MarkerBrowserPage::update_info_text ()
info += "</pre>";
if (item->image () != 0) {
QImage image = item->image ();
if (! image.isNull ()) {
info += "<table border=\"1\" cellspacing=\"0\" cellpadding=\"5\" style=\"border-color:blue; border-style:solid\"><tr><td><p>Snapshot image<br/>(click to enlarge)</p><p><a href=\"show-snapshot\"><img src=\"item.overview-image\"/></a></p></td></tr></table>";
info_text->set_image (*item->image ());
info_text->set_image (image);
}
}
@ -2802,7 +2803,7 @@ MarkerBrowserPage::remove_snapshot_button_clicked ()
if (selected_item->column () == 0) {
const rdb::Item *i = list_model->item (selected_item->row ());
if (i) {
mp_database->set_item_image (i, 0);
mp_database->set_item_image (i, QImage ());
}
}
}
@ -2830,7 +2831,7 @@ MarkerBrowserPage::snapshot_button_clicked ()
const rdb::Item *i = list_model->item (selected_item->row ());
if (i) {
mp_database->set_item_image (i, new QImage (mp_view->get_screenshot ()));
mp_database->set_item_image (i, QImage (mp_view->get_screenshot ()));
markers_list->selectionModel ()->setCurrentIndex (*selected_item, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
update_info_text ();
@ -3125,8 +3126,8 @@ MarkerBrowserPage::info_anchor_clicked (const QUrl &link)
QModelIndex current = markers_list->selectionModel ()->currentIndex ();
const rdb::Item *i = list_model->item (current.row ());
if (i && i->image () != 0) {
MarkerBrowserSnapshotView *snapshot_view = new MarkerBrowserSnapshotView (this, *i->image ());
if (i && i->has_image ()) {
MarkerBrowserSnapshotView *snapshot_view = new MarkerBrowserSnapshotView (this, i->image ());
snapshot_view->exec ();
delete snapshot_view;
#if QT_VERSION < 0x040300

View File

@ -808,16 +808,19 @@ Class<rdb::Item> decl_RdbItem ("rdb", "RdbItem",
"@brief Sets the tags from a string\n"
"@param tags A comma-separated list of tags\n"
) +
#if defined(HAVE_QT)
gsi::method ("image_str", &rdb::Item::image_str,
gsi::method ("has_image?", &rdb::Item::has_image,
"@brief Gets a value indicating that the item has an image attached\n"
"See \\image_str how to obtain the image.\n\n"
"This method has been introduced in version 0.28.\n"
) +
gsi::method ("image_str", &rdb::Item::image_str,
"@brief Gets the image associated with this item as a string\n"
"@return A base64-encoded image file (usually in PNG format)\n"
"@return A base64-encoded image file (in PNG format)\n"
) +
gsi::method ("image_str=", &rdb::Item::set_image_str, gsi::arg ("image"),
"@brief Sets the image from a string\n"
"@param image A base64-encoded image file (preferably in PNG format)\n"
) +
#endif
/* Not supported yet:
gsi::method ("multiplicity", &rdb::Item::multiplicity,
"@brief Gets the item's multiplicity\n"

View File

@ -821,15 +821,7 @@ Item &Item::operator= (const Item &d)
m_visited = d.m_visited;
m_multiplicity = d.m_multiplicity;
m_tag_ids = d.m_tag_ids;
#if defined(HAVE_QT)
if (mp_image.get ()) {
mp_image.reset (0);
}
if (d.mp_image.get ()) {
mp_image.reset (new QImage (*d.mp_image));
}
#endif
m_image_str = d.m_image_str;
}
return *this;
@ -952,48 +944,60 @@ Item::set_tag_str (const std::string &tags)
#if defined(HAVE_QT)
void
Item::set_image (QImage *image)
Item::set_image (const QImage &image)
{
mp_image.reset (image);
}
if (image.isNull ()) {
m_image_str.clear ();
std::string
Item::image_str () const
{
if (! mp_image.get ()) {
return std::string ();
} else {
QByteArray img_data;
QBuffer img_io_device (&img_data);
mp_image->save (&img_io_device, "PNG");
image.save (&img_io_device, "PNG");
return std::string (img_data.toBase64 ().constData ());
m_image_str = std::string (img_data.toBase64 ().constData ());
}
}
void
Item::set_image_str (const std::string &s)
const QImage
Item::image () const
{
if (s.empty ()) {
set_image (0);
if (m_image_str.empty ()) {
return QImage ();
} else {
QByteArray img_data (QByteArray::fromBase64 (QByteArray::fromRawData (s.c_str (), int (s.size ()))));
QByteArray img_data (QByteArray::fromBase64 (QByteArray::fromRawData (m_image_str.c_str (), int (m_image_str.size ()))));
QImage *image = new QImage ();
if (image->loadFromData (img_data)) {
set_image (image);
} else {
delete image;
set_image (0);
}
QImage image;
image.loadFromData (img_data);
return image;
}
}
#endif
bool
Item::has_image () const
{
return !m_image_str.empty ();
}
std::string
Item::image_str () const
{
return m_image_str;
}
void
Item::set_image_str (const std::string &s)
{
m_image_str = s;
}
// ------------------------------------------------------------------------------------------
// Database implementation
@ -1324,13 +1328,20 @@ Database::remove_item_tag (const Item *item, id_type tag)
#if defined(HAVE_QT)
void
Database::set_item_image (const Item *item, QImage *image)
Database::set_item_image (const Item *item, const QImage &image)
{
set_modified ();
const_cast <Item *> (item)->set_image (image);
}
#endif
void
Database::set_item_image_str (const Item *item, const std::string &image_str)
{
set_modified ();
const_cast <Item *> (item)->set_image_str (image_str);
}
void
Database::set_item_multiplicity (const Item *item, size_t n)
{

View File

@ -941,35 +941,37 @@ public:
#if defined(HAVE_QT)
/**
* @brief Get the image object attached to this item
* @brief Gets the image object attached to this item
*
* @return The image object or 0 if no object is attached
* @return The image object or an empty image if no image is attached
*/
const QImage *image () const
{
return mp_image.get ();
}
const QImage image () const;
/**
* @brief Set an image for this item
*
* The image object will become owned by the item
* @brief Set the image for this item
*/
void set_image (QImage *image);
void set_image (const QImage &image);
#endif
/**
* @brief Get an image as a string (base64 coded)
* @brief Gets a value indicating whether the item has an image
*/
bool has_image () const;
/**
* @brief Gets the image as a string (PNG, base64 coded)
*
* Note: if neither PNG support for Qt are compiled in, this string will be empty
*/
std::string image_str () const;
/**
* @brief Get an image from a string (base64 coded)
* @brief Gets the image from a string (PNG, base64 coded)
*
* If the image string is empty, the image will be cleared.
* If the image string is not valid, the image will also be cleared.
*/
void set_image_str (const std::string &s);
#endif
/**
* @brief Get the database reference
@ -998,9 +1000,7 @@ private:
bool m_visited;
std::vector <bool> m_tag_ids;
Database *mp_database;
#if defined(HAVE_QT)
std::unique_ptr<QImage> mp_image;
#endif
std::string m_image_str;
Item ();
@ -2226,9 +2226,14 @@ public:
/**
* @brief Set the image of an item
*/
void set_item_image (const Item *item, QImage *image);
void set_item_image (const Item *item, const QImage &image);
#endif
/**
* @brief Set the image string of an item
*/
void set_item_image_str (const Item *item, const std::string &image_str);
/**
* @brief Set the multiplicity of an item
*/

View File

@ -106,9 +106,7 @@ make_rdb_structure (rdb::Database *rdb)
tl::make_member<std::string, rdb::Item> (&rdb::Item::cell_qname, &rdb::Item::set_cell_qname, "cell") +
tl::make_member<bool, rdb::Item> (&rdb::Item::visited, &rdb::Item::set_visited, "visited") +
tl::make_member<size_t, rdb::Item> (&rdb::Item::multiplicity, &rdb::Item::set_multiplicity, "multiplicity") +
#if defined(HAVE_QT)
tl::make_member<std::string, rdb::Item> (&rdb::Item::image_str, &rdb::Item::set_image_str, "image") +
#endif
tl::make_element<rdb::Values, rdb::Item> (&rdb::Item::values, &rdb::Item::set_values, "values",
tl::make_member<rdb::ValueWrapper, rdb::Values::const_iterator, rdb::Values> (&rdb::Values::begin, &rdb::Values::end, &rdb::Values::add, "value", ValueConverter (rdb))
)

View File

@ -146,7 +146,7 @@ tl::InputStream *get_resource (const char *name)
} else {
auto stream = new tl::InputStream (rr.first);
if (rr.second) {
stream->inflate ();
stream->inflate_always ();
}
return stream;
}

View File

@ -81,8 +81,8 @@ TL_PUBLIC std::pair<tl::InputStreamBase *, bool> get_resource_reader (const char
/**
* @brief Get resource names matching a glob pattern
*
* For example, find_resources("/group/*") will find resources below "group".
* "*" also matches "/", so resources from subgroups will be listed too.
* For example, find_resources("/group*") will find resources whose name start with "group".
* "*" also matches "/"!
*/
TL_PUBLIC std::vector<std::string> find_resources (const std::string &pattern);

View File

@ -143,8 +143,39 @@ public:
// ---------------------------------------------------------------
// InputStream implementation
namespace {
/**
* @brief A dummy delegate to provide for the case of raw data stashed inside the stream itself
*/
class RawDataDelegate
: public InputStreamBase
{
public:
RawDataDelegate (const std::string &source)
: m_source (source)
{ }
virtual size_t read (char *, size_t)
{
return 0;
}
virtual void reset () { }
virtual void close () { }
virtual std::string source () const { return m_source; }
virtual std::string absolute_path () const { return m_source; }
virtual std::string filename () const { return m_source; }
public:
std::string m_source;
};
}
InputStream::InputStream (InputStreamBase &delegate)
: m_pos (0), mp_bptr (0), mp_delegate (&delegate), m_owns_delegate (false), mp_inflate (0)
: m_pos (0), mp_bptr (0), mp_delegate (&delegate), m_owns_delegate (false), mp_inflate (0), m_inflate_always (false)
{
m_bcap = 4096; // initial buffer capacity
m_blen = 0;
@ -152,7 +183,7 @@ InputStream::InputStream (InputStreamBase &delegate)
}
InputStream::InputStream (InputStreamBase *delegate)
: m_pos (0), mp_bptr (0), mp_delegate (delegate), m_owns_delegate (true), mp_inflate (0)
: m_pos (0), mp_bptr (0), mp_delegate (delegate), m_owns_delegate (true), mp_inflate (0), m_inflate_always (false)
{
m_bcap = 4096; // initial buffer capacity
m_blen = 0;
@ -160,7 +191,7 @@ InputStream::InputStream (InputStreamBase *delegate)
}
InputStream::InputStream (const std::string &abstract_path)
: m_pos (0), mp_bptr (0), mp_delegate (0), m_owns_delegate (false), mp_inflate (0)
: m_pos (0), mp_bptr (0), mp_delegate (0), m_owns_delegate (false), mp_inflate (0), m_inflate_always (false)
{
m_bcap = 4096; // initial buffer capacity
m_blen = 0;
@ -175,28 +206,30 @@ InputStream::InputStream (const std::string &abstract_path)
#if defined(HAVE_QT)
QResource res (tl::to_qstring (abstract_path));
if (res.size () > 0) {
QByteArray data;
#if QT_VERSION >= 0x60000
if (res.compressionAlgorithm () == QResource::ZlibCompression) {
#else
if (res.isCompressed ()) {
#endif
data = qUncompress ((const unsigned char *)res.data (), (int)res.size ());
} else {
data = QByteArray ((const char *)res.data (), (int)res.size ());
}
mp_buffer = new char[data.size ()];
memcpy (mp_buffer, data.constData (), data.size ());
mp_bptr = mp_buffer;
m_bcap = data.size ();
m_blen = m_bcap;
if (res.size () == 0) {
throw tl::Exception (tl::to_string (tr ("Resource not found: ")) + abstract_path);
}
QByteArray data;
#if QT_VERSION >= 0x60000
if (res.compressionAlgorithm () == QResource::ZlibCompression) {
#else
if (res.isCompressed ()) {
#endif
data = qUncompress ((const unsigned char *)res.data (), (int)res.size ());
} else {
data = QByteArray ((const char *)res.data (), (int)res.size ());
}
mp_buffer = new char[data.size ()];
memcpy (mp_buffer, data.constData (), data.size ());
mp_bptr = mp_buffer;
m_bcap = data.size ();
m_blen = m_bcap;
mp_delegate = new RawDataDelegate (abstract_path);
#else
std::pair<tl::InputStreamBase *, bool> rr = tl::get_resource_reader (ex.get ());
@ -240,7 +273,7 @@ InputStream::InputStream (const std::string &abstract_path)
m_owns_delegate = true;
if (needs_inflate) {
inflate ();
inflate_always ();
}
}
@ -441,6 +474,13 @@ InputStream::inflate ()
mp_inflate = new tl::InflateFilter (*this);
}
void
InputStream::inflate_always ()
{
m_inflate_always = true;
reset ();
}
void
InputStream::close ()
{
@ -468,6 +508,8 @@ InputStream::reset ()
} else {
tl_assert (mp_delegate != 0);
mp_delegate->reset ();
m_pos = 0;
@ -481,6 +523,10 @@ InputStream::reset ()
mp_buffer = new char [m_bcap];
}
if (m_inflate_always) {
inflate ();
}
}
// ---------------------------------------------------------------

View File

@ -466,6 +466,15 @@ public:
*/
void inflate ();
/**
* @brief Enables "inflate" right from the beginning
*
* Contrary to "inflate" (which is temporary), this version enables
* decompression right from the beginning of the file. It does a "reset"
* implicitly.
*/
void inflate_always ();
/**
* @brief Obtain the current file position
*/
@ -557,6 +566,7 @@ private:
// inflate support
InflateFilter *mp_inflate;
bool m_inflate_always;
// No copying currently
InputStream (const InputStream &);

View File

@ -607,6 +607,14 @@ main_cont (int &argc, char **argv)
tl::set_continue_flag (continue_flag);
tl::set_debug_mode (debug_mode);
// set some global variables
if (rba::RubyInterpreter::instance ()) {
rba::RubyInterpreter::instance ()->define_variable ("ut_inst_path", tl::get_inst_path ());
}
if (pya::PythonInterpreter::instance ()) {
pya::PythonInterpreter::instance ()->define_variable ("ut_inst_path", tl::get_inst_path ());
}
FILE *output_file = 0;
try {

View File

@ -32,7 +32,7 @@ load("test_prologue.rb")
class Buddies_TestClass < TestBase
def buddy_bin(name)
file = File.join(RBA::Application::instance.inst_path, name)
file = File.join($ut_inst_path, name)
return file
end

View File

@ -69,7 +69,7 @@ class DBGlyph_TestClass < TestBase
tg.load_from_resource(":/fonts/does_not_exist.gds")
assert_equal(false, true)
rescue => ex
assert_equal(ex.to_s, "Unable to load font resource from :/fonts/does_not_exist.gds in TextGenerator::load_from_resource")
assert_equal(ex.to_s, "Resource not found: :/fonts/does_not_exist.gds in TextGenerator::load_from_resource")
end
end