Commit bf44e21ad6728c825ed4e28fceba190a68435ab0
1 parent
94463713
Update several c-api functions to take string buffers as input
Instead of returning references to static memory (which are invalidated by subsequent or concurrent calls to the function), require users to input string buffers to functions that return strings. Affected functions: br_get_filename br_get_metadata_string br_scratch_path br_objects br_most_recent_message In some GUI functions, use C++ functions instead of going through the c api add a c++ method correspondign to br_objects (which returns a stringlist instead of merging the lines) br_read_pipe and br_get_header also use static memory in a similar way, but are not addressed in this commit.
Showing
10 changed files
with
113 additions
and
72 deletions
app/br/br.cpp
| @@ -171,7 +171,11 @@ public: | @@ -171,7 +171,11 @@ public: | ||
| 171 | // Do nothing because we checked for this flag prior to initialization | 171 | // Do nothing because we checked for this flag prior to initialization |
| 172 | } else if (!strcmp(fun, "objects")) { | 172 | } else if (!strcmp(fun, "objects")) { |
| 173 | check(parc <= 2, "Incorrect parameter count for 'objects'."); | 173 | check(parc <= 2, "Incorrect parameter count for 'objects'."); |
| 174 | - printf("%s\n", br_objects(parc >= 1 ? parv[0] : ".*", parc >= 2 ? parv[1] : ".*")); | 174 | + int size = br_objects(NULL, 0, parc >= 1 ? parv[0] : ".*", parc >= 2 ? parv[1] : ".*"); |
| 175 | + char * temp = new char[size]; | ||
| 176 | + br_objects(temp, size, parc >= 1 ? parv[0] : ".*", parc >= 2 ? parv[1] : ".*"); | ||
| 177 | + printf("%s\n", temp); | ||
| 178 | + delete [] temp; | ||
| 175 | } else if (!strcmp(fun, "about")) { | 179 | } else if (!strcmp(fun, "about")) { |
| 176 | check(parc == 0, "No parameters expected for 'about'."); | 180 | check(parc == 0, "No parameters expected for 'about'."); |
| 177 | printf("%s\n", br_about()); | 181 | printf("%s\n", br_about()); |
openbr/gui/algorithm.cpp
| 1 | #include <QStringList> | 1 | #include <QStringList> |
| 2 | #include <openbr/openbr.h> | 2 | #include <openbr/openbr.h> |
| 3 | +#include <openbr/openbr_plugin.h> | ||
| 3 | 4 | ||
| 4 | #include "algorithm.h" | 5 | #include "algorithm.h" |
| 5 | 6 | ||
| @@ -18,7 +19,7 @@ bool br::Algorithm::addAlgorithm(const QString &algorithm, const QString &displa | @@ -18,7 +19,7 @@ bool br::Algorithm::addAlgorithm(const QString &algorithm, const QString &displa | ||
| 18 | { | 19 | { |
| 19 | static QStringList availableAlgorithms; | 20 | static QStringList availableAlgorithms; |
| 20 | if (availableAlgorithms.isEmpty()) | 21 | if (availableAlgorithms.isEmpty()) |
| 21 | - availableAlgorithms = QString(br_objects("Abbreviation", ".*", false)).split("\n"); | 22 | + availableAlgorithms = br::Context::objects("Abbreviation", ".*", false); |
| 22 | 23 | ||
| 23 | if (!availableAlgorithms.contains(algorithm)) | 24 | if (!availableAlgorithms.contains(algorithm)) |
| 24 | return false; | 25 | return false; |
openbr/gui/gallerytoolbar.cpp
| @@ -84,7 +84,7 @@ void br::GalleryToolBar::_enroll(const br::File &input) | @@ -84,7 +84,7 @@ void br::GalleryToolBar::_enroll(const br::File &input) | ||
| 84 | galleryLock.lock(); | 84 | galleryLock.lock(); |
| 85 | this->input = input; | 85 | this->input = input; |
| 86 | if (input.suffix() == "gal") gallery = input.name + ".mem"; | 86 | if (input.suffix() == "gal") gallery = input.name + ".mem"; |
| 87 | - else gallery = QString("%1/galleries/%2.gal[cache]").arg(br_scratch_path(), qPrintable(input.baseName()+input.hash())); | 87 | + else gallery = QString("%1/galleries/%2.gal[cache]").arg(br::Globals->scratchPath(), qPrintable(input.baseName()+input.hash())); |
| 88 | files = br::Enroll(input.flat(), gallery.flat()); | 88 | files = br::Enroll(input.flat(), gallery.flat()); |
| 89 | galleryLock.unlock(); | 89 | galleryLock.unlock(); |
| 90 | } | 90 | } |
| @@ -148,7 +148,7 @@ void br::GalleryToolBar::home() | @@ -148,7 +148,7 @@ void br::GalleryToolBar::home() | ||
| 148 | 148 | ||
| 149 | void br::GalleryToolBar::mean() | 149 | void br::GalleryToolBar::mean() |
| 150 | { | 150 | { |
| 151 | - const QString file = QString("%1/mean/%2.png").arg(br_scratch_path(), input.baseName()+input.hash()); | 151 | + const QString file = QString("%1/mean/%2.png").arg(br::Globals->scratchPath(), input.baseName()+input.hash()); |
| 152 | br_set_property("CENTER_TRAIN_B", qPrintable(file)); | 152 | br_set_property("CENTER_TRAIN_B", qPrintable(file)); |
| 153 | br::File trainingFile = input; | 153 | br::File trainingFile = input; |
| 154 | br_train(qPrintable(trainingFile.flat()), "[algorithm=MedianFace]"); | 154 | br_train(qPrintable(trainingFile.flat()), "[algorithm=MedianFace]"); |
openbr/gui/progress.cpp
| 1 | #include <openbr/openbr.h> | 1 | #include <openbr/openbr.h> |
| 2 | +#include <openbr/openbr_plugin.h> | ||
| 2 | 3 | ||
| 3 | #include "progress.h" | 4 | #include "progress.h" |
| 4 | 5 | ||
| @@ -29,7 +30,7 @@ void br::Progress::checkProgress() | @@ -29,7 +30,7 @@ void br::Progress::checkProgress() | ||
| 29 | const bool visible = progress >= 0 && progress < 100; | 30 | const bool visible = progress >= 0 && progress < 100; |
| 30 | 31 | ||
| 31 | if (visible) { | 32 | if (visible) { |
| 32 | - showMessage(br_most_recent_message()); | 33 | + showMessage(Globals->mostRecentMessage); |
| 33 | pbProgress.setValue(progress); | 34 | pbProgress.setValue(progress); |
| 34 | if (progress > 100) pbProgress.setMaximum(0); | 35 | if (progress > 100) pbProgress.setMaximum(0); |
| 35 | else pbProgress.setMaximum(100); | 36 | else pbProgress.setMaximum(100); |
openbr/gui/templateviewer.cpp
| @@ -72,7 +72,7 @@ void TemplateViewer::refreshImage() | @@ -72,7 +72,7 @@ void TemplateViewer::refreshImage() | ||
| 72 | if (file.isNull() || (format == "Photo")) { | 72 | if (file.isNull() || (format == "Photo")) { |
| 73 | setImage(file, true); | 73 | setImage(file, true); |
| 74 | } else { | 74 | } else { |
| 75 | - const QString path = QString(br_scratch_path()) + "/thumbnails"; | 75 | + const QString path = QString(br::Globals->scratchPath()) + "/thumbnails"; |
| 76 | const QString hash = file.hash()+format; | 76 | const QString hash = file.hash()+format; |
| 77 | const QString processedFile = path+"/"+file.baseName()+hash+".png"; | 77 | const QString processedFile = path+"/"+file.baseName()+hash+".png"; |
| 78 | if (!QFileInfo(processedFile).exists()) { | 78 | if (!QFileInfo(processedFile).exists()) { |
openbr/gui/transformeditor.cpp
| @@ -24,7 +24,7 @@ using namespace br; | @@ -24,7 +24,7 @@ using namespace br; | ||
| 24 | br::TransformEditor::TransformEditor(Transform *transform, QWidget *parent) | 24 | br::TransformEditor::TransformEditor(Transform *transform, QWidget *parent) |
| 25 | : QWidget(parent) | 25 | : QWidget(parent) |
| 26 | { | 26 | { |
| 27 | - name.addItems(QString(br_objects("Transform", ".*", false)).split('\n')); | 27 | + name.addItems(br::Context::objects("Transform", ".*", false)); |
| 28 | layout.addWidget(&name); | 28 | layout.addWidget(&name); |
| 29 | setLayout(&layout); | 29 | setLayout(&layout); |
| 30 | 30 |
openbr/openbr.cpp
| @@ -28,6 +28,21 @@ | @@ -28,6 +28,21 @@ | ||
| 28 | 28 | ||
| 29 | using namespace br; | 29 | using namespace br; |
| 30 | 30 | ||
| 31 | +static int partialCopy(const QString & string, char * buffer, int buffer_length) | ||
| 32 | +{ | ||
| 33 | + | ||
| 34 | + QByteArray byteArray = string.toLocal8Bit(); | ||
| 35 | + | ||
| 36 | + int copyLength = std::min(buffer_length-1, byteArray.size()); | ||
| 37 | + if (copyLength < 0) | ||
| 38 | + return byteArray.size() + 1; | ||
| 39 | + | ||
| 40 | + memcpy(buffer, byteArray.data(), copyLength); | ||
| 41 | + buffer[copyLength] = '\0'; | ||
| 42 | + | ||
| 43 | + return byteArray.size() + 1; | ||
| 44 | +} | ||
| 45 | + | ||
| 31 | const char *br_about() | 46 | const char *br_about() |
| 32 | { | 47 | { |
| 33 | static QMutex aboutLock; | 48 | static QMutex aboutLock; |
| @@ -153,53 +168,14 @@ void br_make_pairwise_mask(const char *target_input, const char *query_input, co | @@ -153,53 +168,14 @@ void br_make_pairwise_mask(const char *target_input, const char *query_input, co | ||
| 153 | BEE::makePairwiseMask(target_input, query_input, mask); | 168 | BEE::makePairwiseMask(target_input, query_input, mask); |
| 154 | } | 169 | } |
| 155 | 170 | ||
| 156 | -const char *br_most_recent_message() | 171 | +int br_most_recent_message(char * buffer, int buffer_length) |
| 157 | { | 172 | { |
| 158 | - static QByteArray byteArray; | ||
| 159 | - byteArray = Globals->mostRecentMessage.toLocal8Bit(); | ||
| 160 | - return byteArray.data(); | 173 | + return partialCopy(Globals->mostRecentMessage, buffer, buffer_length); |
| 161 | } | 174 | } |
| 162 | 175 | ||
| 163 | -const char *br_objects(const char *abstractions, const char *implementations, bool parameters) | 176 | +int br_objects(char * buffer, int buffer_length, const char *abstractions, const char *implementations, bool parameters) |
| 164 | { | 177 | { |
| 165 | - static QByteArray objects; | ||
| 166 | - | ||
| 167 | - QStringList objectList; | ||
| 168 | - QRegExp abstractionsRegExp(abstractions); | ||
| 169 | - QRegExp implementationsRegExp(implementations); | ||
| 170 | - | ||
| 171 | - if (abstractionsRegExp.exactMatch("Abbreviation")) | ||
| 172 | - foreach (const QString &name, Globals->abbreviations.keys()) | ||
| 173 | - if (implementationsRegExp.exactMatch(name)) | ||
| 174 | - objectList.append(name + (parameters ? "\t" + Globals->abbreviations[name] : "")); | ||
| 175 | - | ||
| 176 | - if (abstractionsRegExp.exactMatch("Distance")) | ||
| 177 | - foreach (const QString &name, Factory<Distance>::names()) | ||
| 178 | - if (implementationsRegExp.exactMatch(name)) | ||
| 179 | - objectList.append(name + (parameters ? "\t" + Factory<Distance>::parameters(name) : "")); | ||
| 180 | - | ||
| 181 | - if (abstractionsRegExp.exactMatch("Format")) | ||
| 182 | - foreach (const QString &name, Factory<Format>::names()) | ||
| 183 | - if (implementationsRegExp.exactMatch(name)) | ||
| 184 | - objectList.append(name + (parameters ? "\t" + Factory<Format>::parameters(name) : "")); | ||
| 185 | - | ||
| 186 | - if (abstractionsRegExp.exactMatch("Initializer")) | ||
| 187 | - foreach (const QString &name, Factory<Initializer>::names()) | ||
| 188 | - if (implementationsRegExp.exactMatch(name)) | ||
| 189 | - objectList.append(name + (parameters ? "\t" + Factory<Initializer>::parameters(name) : "")); | ||
| 190 | - | ||
| 191 | - if (abstractionsRegExp.exactMatch("Output")) | ||
| 192 | - foreach (const QString &name, Factory<Output>::names()) | ||
| 193 | - if (implementationsRegExp.exactMatch(name)) | ||
| 194 | - objectList.append(name + (parameters ? "\t" + Factory<Output>::parameters(name) : "")); | ||
| 195 | - | ||
| 196 | - if (abstractionsRegExp.exactMatch("Transform")) | ||
| 197 | - foreach (const QString &name, Factory<Transform>::names()) | ||
| 198 | - if (implementationsRegExp.exactMatch(name)) | ||
| 199 | - objectList.append(name + (parameters ? "\t" + Factory<Transform>::parameters(name) : "")); | ||
| 200 | - | ||
| 201 | - objects = objectList.join("\n").toLocal8Bit(); | ||
| 202 | - return objects.data(); | 178 | + return partialCopy(br::Context::objects(abstractions, implementations, parameters).join('\n'), buffer, buffer_length); |
| 203 | } | 179 | } |
| 204 | 180 | ||
| 205 | bool br_plot(int num_files, const char *files[], const char *destination, bool show) | 181 | bool br_plot(int num_files, const char *files[], const char *destination, bool show) |
| @@ -254,11 +230,9 @@ void br_read_pipe(const char *pipe, int *argc, char ***argv) | @@ -254,11 +230,9 @@ void br_read_pipe(const char *pipe, int *argc, char ***argv) | ||
| 254 | *argv = rawCharArrayList.data(); | 230 | *argv = rawCharArrayList.data(); |
| 255 | } | 231 | } |
| 256 | 232 | ||
| 257 | -const char *br_scratch_path() | 233 | +int br_scratch_path(char * buffer, int buffer_length) |
| 258 | { | 234 | { |
| 259 | - static QByteArray byteArray; | ||
| 260 | - byteArray = Context::scratchPath().toLocal8Bit(); | ||
| 261 | - return byteArray.data(); | 235 | + return partialCopy(Context::scratchPath(), buffer, buffer_length); |
| 262 | } | 236 | } |
| 263 | 237 | ||
| 264 | const char *br_sdk_path() | 238 | const char *br_sdk_path() |
| @@ -387,11 +361,9 @@ bool br_img_is_empty(br_template tmpl) | @@ -387,11 +361,9 @@ bool br_img_is_empty(br_template tmpl) | ||
| 387 | return t->m().empty(); | 361 | return t->m().empty(); |
| 388 | } | 362 | } |
| 389 | 363 | ||
| 390 | -const char* br_get_filename(br_template tmpl) | 364 | +int br_get_filename(br_template tmpl, char * buffer, int buffer_length) |
| 391 | { | 365 | { |
| 392 | - static QByteArray buffer; | ||
| 393 | - buffer = reinterpret_cast<Template*>(tmpl)->file.name.toLocal8Bit(); | ||
| 394 | - return buffer.data(); | 366 | + return partialCopy(reinterpret_cast<Template*>(tmpl)->file.name, buffer, buffer_length); |
| 395 | } | 367 | } |
| 396 | 368 | ||
| 397 | void br_set_filename(br_template tmpl, const char *filename) | 369 | void br_set_filename(br_template tmpl, const char *filename) |
| @@ -400,15 +372,11 @@ void br_set_filename(br_template tmpl, const char *filename) | @@ -400,15 +372,11 @@ void br_set_filename(br_template tmpl, const char *filename) | ||
| 400 | t->file.name = filename; | 372 | t->file.name = filename; |
| 401 | } | 373 | } |
| 402 | 374 | ||
| 403 | -const char* br_get_metadata_string(br_template tmpl, const char *key) | 375 | +int br_get_metadata_string(br_template tmpl, const char *key, char * buffer, int buffer_length) |
| 404 | { | 376 | { |
| 405 | Template *t = reinterpret_cast<Template*>(tmpl); | 377 | Template *t = reinterpret_cast<Template*>(tmpl); |
| 406 | - // need an object outside of this scope | ||
| 407 | - // so the char pointer is valid | ||
| 408 | - static QByteArray result; | ||
| 409 | QVariant qvar = t->file.value(key); | 378 | QVariant qvar = t->file.value(key); |
| 410 | - result = QtUtils::toString(qvar).toUtf8(); | ||
| 411 | - return result.data(); | 379 | + return partialCopy(QtUtils::toString(qvar), buffer, buffer_length); |
| 412 | } | 380 | } |
| 413 | 381 | ||
| 414 | br_template_list br_enroll_template(br_template tmpl) | 382 | br_template_list br_enroll_template(br_template tmpl) |
openbr/openbr.h
| @@ -41,6 +41,10 @@ extern "C" { | @@ -41,6 +41,10 @@ extern "C" { | ||
| 41 | * \section managed_return_value Managed Return Value | 41 | * \section managed_return_value Managed Return Value |
| 42 | * Memory for <tt>const char*</tt> return values is managed internally and guaranteed until the next call to the function. | 42 | * Memory for <tt>const char*</tt> return values is managed internally and guaranteed until the next call to the function. |
| 43 | * | 43 | * |
| 44 | + * \section input_string_buffer Input String Buffer | ||
| 45 | + * Users should input a char * buffer and the size of that buffer. String data will be copied into the buffer, if the buffer is too | ||
| 46 | + * small, only part of the string will be copied. Returns the buffer size required to contain the complete string. | ||
| 47 | + * | ||
| 44 | * \section examples Examples | 48 | * \section examples Examples |
| 45 | * - \ref c_face_recognition_evaluation | 49 | * - \ref c_face_recognition_evaluation |
| 46 | * | 50 | * |
| @@ -255,10 +259,10 @@ BR_EXPORT void br_make_pairwise_mask(const char *target_input, const char *query | @@ -255,10 +259,10 @@ BR_EXPORT void br_make_pairwise_mask(const char *target_input, const char *query | ||
| 255 | 259 | ||
| 256 | /*! | 260 | /*! |
| 257 | * \brief Returns the most recent line sent to stderr. | 261 | * \brief Returns the most recent line sent to stderr. |
| 258 | - * \note \ref managed_return_value | 262 | + * \note \ref input_string_buffer |
| 259 | * \see br_progress br_time_remaining | 263 | * \see br_progress br_time_remaining |
| 260 | */ | 264 | */ |
| 261 | -BR_EXPORT const char *br_most_recent_message(); | 265 | +BR_EXPORT int br_most_recent_message(char * buffer, int buffer_length); |
| 262 | 266 | ||
| 263 | /*! | 267 | /*! |
| 264 | * \brief Returns names and parameters for the requested objects. | 268 | * \brief Returns names and parameters for the requested objects. |
| @@ -267,10 +271,10 @@ BR_EXPORT const char *br_most_recent_message(); | @@ -267,10 +271,10 @@ BR_EXPORT const char *br_most_recent_message(); | ||
| 267 | * \param abstractions Regular expression of the abstractions to search. | 271 | * \param abstractions Regular expression of the abstractions to search. |
| 268 | * \param implementations Regular expression of the implementations to search. | 272 | * \param implementations Regular expression of the implementations to search. |
| 269 | * \param parameters Include parameters after object name. | 273 | * \param parameters Include parameters after object name. |
| 270 | - * \note \ref managed_return_value | 274 | + * \note \ref input_string_buffer |
| 271 | * \note This function uses Qt's <a href="http://doc.qt.digia.com/stable/qregexp.html">QRegExp</a> syntax. | 275 | * \note This function uses Qt's <a href="http://doc.qt.digia.com/stable/qregexp.html">QRegExp</a> syntax. |
| 272 | */ | 276 | */ |
| 273 | -BR_EXPORT const char *br_objects(const char *abstractions = ".*", const char *implementations = ".*", bool parameters = true); | 277 | +BR_EXPORT int br_objects(char * buffer, int buffer_length, const char *abstractions = ".*", const char *implementations = ".*", bool parameters = true); |
| 274 | 278 | ||
| 275 | /*! | 279 | /*! |
| 276 | * \brief Renders recognition performance figures for a set of <tt>.csv</tt> files created by \ref br_eval. | 280 | * \brief Renders recognition performance figures for a set of <tt>.csv</tt> files created by \ref br_eval. |
| @@ -375,9 +379,11 @@ BR_EXPORT void br_read_pipe(const char *pipe, int *argc, char ***argv); | @@ -375,9 +379,11 @@ BR_EXPORT void br_read_pipe(const char *pipe, int *argc, char ***argv); | ||
| 375 | 379 | ||
| 376 | /*! | 380 | /*! |
| 377 | * \brief Wraps br::Context::scratchPath() | 381 | * \brief Wraps br::Context::scratchPath() |
| 382 | + * \note \ref input_string_buffer | ||
| 378 | * \see br_version | 383 | * \see br_version |
| 379 | */ | 384 | */ |
| 380 | -BR_EXPORT const char *br_scratch_path(); | 385 | +BR_EXPORT int br_scratch_path(char * buffer, int buffer_length); |
| 386 | + | ||
| 381 | 387 | ||
| 382 | /*! | 388 | /*! |
| 383 | * \brief Returns the full path to the root of the SDK. | 389 | * \brief Returns the full path to the root of the SDK. |
| @@ -433,7 +439,6 @@ BR_EXPORT void br_train_n(int num_inputs, const char *inputs[], const char *mode | @@ -433,7 +439,6 @@ BR_EXPORT void br_train_n(int num_inputs, const char *inputs[], const char *mode | ||
| 433 | 439 | ||
| 434 | /*! | 440 | /*! |
| 435 | * \brief Wraps br::Context::version() | 441 | * \brief Wraps br::Context::version() |
| 436 | - * \note \ref managed_return_value | ||
| 437 | * \see br_about br_scratch_path | 442 | * \see br_about br_scratch_path |
| 438 | */ | 443 | */ |
| 439 | BR_EXPORT const char *br_version(); | 444 | BR_EXPORT const char *br_version(); |
| @@ -505,16 +510,18 @@ BR_EXPORT int br_img_channels(br_template tmpl); | @@ -505,16 +510,18 @@ BR_EXPORT int br_img_channels(br_template tmpl); | ||
| 505 | BR_EXPORT bool br_img_is_empty(br_template tmpl); | 510 | BR_EXPORT bool br_img_is_empty(br_template tmpl); |
| 506 | /*! | 511 | /*! |
| 507 | * \brief Get the filename for a br::Template | 512 | * \brief Get the filename for a br::Template |
| 513 | + * \note \ref input_string_buffer | ||
| 508 | */ | 514 | */ |
| 509 | -BR_EXPORT const char* br_get_filename(br_template tmpl); | 515 | +BR_EXPORT int br_get_filename(br_template tmpl, char * buffer, int buffer_length); |
| 510 | /*! | 516 | /*! |
| 511 | * \brief Set the filename for a br::Template. | 517 | * \brief Set the filename for a br::Template. |
| 512 | */ | 518 | */ |
| 513 | BR_EXPORT void br_set_filename(br_template tmpl, const char *filename); | 519 | BR_EXPORT void br_set_filename(br_template tmpl, const char *filename); |
| 514 | /*! | 520 | /*! |
| 515 | * \brief Get metadata as a string for the given key in the given template. | 521 | * \brief Get metadata as a string for the given key in the given template. |
| 522 | + * \note \ref input_string_buffer | ||
| 516 | */ | 523 | */ |
| 517 | -BR_EXPORT const char* br_get_metadata_string(br_template, const char *key); | 524 | +BR_EXPORT int br_get_metadata_string(br_template, const char *key, char * buffer, int buffer_length); |
| 518 | /*! | 525 | /*! |
| 519 | * \brief Enroll a br::Template from the C API! Returns a pointer to a br::TemplateList | 526 | * \brief Enroll a br::Template from the C API! Returns a pointer to a br::TemplateList |
| 520 | * \param tmpl Pointer to a br::Template. | 527 | * \param tmpl Pointer to a br::Template. |
openbr/openbr_plugin.cpp
| @@ -203,6 +203,13 @@ QList<QRectF> File::namedRects() const | @@ -203,6 +203,13 @@ QList<QRectF> File::namedRects() const | ||
| 203 | const QVariant &variant = m_metadata[key]; | 203 | const QVariant &variant = m_metadata[key]; |
| 204 | if (variant.canConvert<QRectF>()) | 204 | if (variant.canConvert<QRectF>()) |
| 205 | rects.append(variant.value<QRectF>()); | 205 | rects.append(variant.value<QRectF>()); |
| 206 | + else if(variant.canConvert<QList<QRectF> >()) { | ||
| 207 | + QList<QRectF> list = variant.value<QList<QRectF> >(); | ||
| 208 | + for (int i=0;i < list.size();i++) | ||
| 209 | + { | ||
| 210 | + rects.append(list[i]); | ||
| 211 | + } | ||
| 212 | + } | ||
| 206 | } | 213 | } |
| 207 | return rects; | 214 | return rects; |
| 208 | } | 215 | } |
| @@ -1009,6 +1016,47 @@ QString br::Context::scratchPath() | @@ -1009,6 +1016,47 @@ QString br::Context::scratchPath() | ||
| 1009 | return QString("%1/%2-%3.%4").arg(QDir::homePath(), PRODUCT_NAME, QString::number(PRODUCT_VERSION_MAJOR), QString::number(PRODUCT_VERSION_MINOR)); | 1016 | return QString("%1/%2-%3.%4").arg(QDir::homePath(), PRODUCT_NAME, QString::number(PRODUCT_VERSION_MAJOR), QString::number(PRODUCT_VERSION_MINOR)); |
| 1010 | } | 1017 | } |
| 1011 | 1018 | ||
| 1019 | + | ||
| 1020 | +QStringList br::Context::objects(const char *abstractions, const char *implementations, bool parameters) | ||
| 1021 | +{ | ||
| 1022 | + QStringList objectList; | ||
| 1023 | + QRegExp abstractionsRegExp(abstractions); | ||
| 1024 | + QRegExp implementationsRegExp(implementations); | ||
| 1025 | + | ||
| 1026 | + if (abstractionsRegExp.exactMatch("Abbreviation")) | ||
| 1027 | + foreach (const QString &name, Globals->abbreviations.keys()) | ||
| 1028 | + if (implementationsRegExp.exactMatch(name)) | ||
| 1029 | + objectList.append(name + (parameters ? "\t" + Globals->abbreviations[name] : "")); | ||
| 1030 | + | ||
| 1031 | + if (abstractionsRegExp.exactMatch("Distance")) | ||
| 1032 | + foreach (const QString &name, Factory<Distance>::names()) | ||
| 1033 | + if (implementationsRegExp.exactMatch(name)) | ||
| 1034 | + objectList.append(name + (parameters ? "\t" + Factory<Distance>::parameters(name) : "")); | ||
| 1035 | + | ||
| 1036 | + if (abstractionsRegExp.exactMatch("Format")) | ||
| 1037 | + foreach (const QString &name, Factory<Format>::names()) | ||
| 1038 | + if (implementationsRegExp.exactMatch(name)) | ||
| 1039 | + objectList.append(name + (parameters ? "\t" + Factory<Format>::parameters(name) : "")); | ||
| 1040 | + | ||
| 1041 | + if (abstractionsRegExp.exactMatch("Initializer")) | ||
| 1042 | + foreach (const QString &name, Factory<Initializer>::names()) | ||
| 1043 | + if (implementationsRegExp.exactMatch(name)) | ||
| 1044 | + objectList.append(name + (parameters ? "\t" + Factory<Initializer>::parameters(name) : "")); | ||
| 1045 | + | ||
| 1046 | + if (abstractionsRegExp.exactMatch("Output")) | ||
| 1047 | + foreach (const QString &name, Factory<Output>::names()) | ||
| 1048 | + if (implementationsRegExp.exactMatch(name)) | ||
| 1049 | + objectList.append(name + (parameters ? "\t" + Factory<Output>::parameters(name) : "")); | ||
| 1050 | + | ||
| 1051 | + if (abstractionsRegExp.exactMatch("Transform")) | ||
| 1052 | + foreach (const QString &name, Factory<Transform>::names()) | ||
| 1053 | + if (implementationsRegExp.exactMatch(name)) | ||
| 1054 | + objectList.append(name + (parameters ? "\t" + Factory<Transform>::parameters(name) : "")); | ||
| 1055 | + | ||
| 1056 | + | ||
| 1057 | + return objectList; | ||
| 1058 | +} | ||
| 1059 | + | ||
| 1012 | void br::Context::messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) | 1060 | void br::Context::messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) |
| 1013 | { | 1061 | { |
| 1014 | // Something about this method is not thread safe, and will lead to crashes if qDebug | 1062 | // Something about this method is not thread safe, and will lead to crashes if qDebug |
openbr/openbr_plugin.h
| @@ -830,6 +830,18 @@ public: | @@ -830,6 +830,18 @@ public: | ||
| 830 | */ | 830 | */ |
| 831 | static QString scratchPath(); | 831 | static QString scratchPath(); |
| 832 | 832 | ||
| 833 | + /*! | ||
| 834 | + * \brief Returns names and parameters for the requested objects. | ||
| 835 | + * | ||
| 836 | + * Each object is \c \\n seperated. Arguments are seperated from the object name with a \c \\t. | ||
| 837 | + * \param abstractions Regular expression of the abstractions to search. | ||
| 838 | + * \param implementations Regular expression of the implementations to search. | ||
| 839 | + * \param parameters Include parameters after object name. | ||
| 840 | + * \note \ref managed_return_value | ||
| 841 | + * \note This function uses Qt's <a href="http://doc.qt.digia.com/stable/qregexp.html">QRegExp</a> syntax. | ||
| 842 | + */ | ||
| 843 | + static QStringList objects(const char *abstractions = ".*", const char *implementations = ".*", bool parameters = true); | ||
| 844 | + | ||
| 833 | private: | 845 | private: |
| 834 | static void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg); | 846 | static void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg); |
| 835 | }; | 847 | }; |