detail::CallId callId;
detail::displayDebugCallInfoSignal(callId, signalName, info, connectionInfo->interfaceName);
auto callbackLambda = [ callId, connectionState = this->connectionState, callback, signalName, connectionInfo = this->connectionInfo ]
- (const Eldbus_Message * msg) -> void {
+ (const Eldbus_Message * msg) -> void {
const char *errname, *aux;
if (eldbus_message_error_get(msg, &errname, &aux))
{
#include <algorithm>
static constexpr int DASHED_LINE_LENGTH = 20;
-static constexpr int DEFAULT_LINE_THICKNESS = 10;
-
-#define DEFAULT_LINE_COLOUR 255, 0, 0, 255
-#define DEFAULT_RECTANGLE_COLOUR 0, 255, 0, 255
+static constexpr int DEFAULT_LINE_THICKNESS = 5;
std::string Point::toString() const
{
return rect;
}
+
+Color::Color(int r, int g, int b, int a)
+ : r(r & 0xff), g(g & 0xff), b(b & 0xff), a(a & 0xff)
+{
+}
+
+int Color::getR() const
+{
+ return r;
+}
+
+int Color::getG() const
+{
+ return g;
+}
+
+int Color::getB() const
+{
+ return b;
+}
+
+int Color::getA() const
+{
+ return a;
+}
+
+int Color::toRGBAInt() const
+{
+ return (r << 24) | (g << 16) | (b << 8) | a;
+}
+
+Color Color::invert() const
+{
+ return {0xff - r, 0xff - g, 0xff - b, a};
+}
+
+Color Color::fromRGBA(int rgba)
+{
+ return {rgba >> 24, rgba >> 16, rgba >> 8, rgba};
+}
+
+Color Color::fromABGR(int abgr)
+{
+ return {abgr, abgr >> 8, abgr >> 16, abgr >> 24};
+}
+
namespace
{
- evas::Object createAndShowThinLine(Evas *evasCanvas, Rectangle dimensions)
+ evas::Object createAndShowThinLine(Evas *evasCanvas, Rectangle dimensions, Color color)
{
auto line = evas_object_line_add(evasCanvas);
evas_object_line_xy_set(line, dimensions.position.x, dimensions.position.y,
dimensions.position.x + dimensions.size.width, dimensions.position.y + dimensions.size.height);
- evas_object_color_set(line, DEFAULT_LINE_COLOUR);
+ evas_object_color_set(line, color.getR(), color.getG(), color.getB(), color.getA());
evas_object_show(line);
return evas::Object{line};
}
- evas::Object createAndShowRectangle(Evas *evasCanvas, Rectangle dimensions)
+ evas::Object createAndShowRectangle(Evas *evasCanvas, Rectangle dimensions, Color color)
{
auto rect = evas_object_rectangle_add(evasCanvas);
evas_object_move(rect, dimensions.position.x, dimensions.position.y);
evas_object_resize(rect, dimensions.size.width, dimensions.size.height);
- evas_object_color_set(rect, DEFAULT_RECTANGLE_COLOUR);
+ evas_object_color_set(rect, color.getR(), color.getG(), color.getB(), color.getA());
evas_object_show(rect);
return evas::Object{rect};
}
- evas::Object createAndShowThickLine(Evas *evasCanvas, Rectangle dimensions)
+ evas::Object createAndShowThickLine(Evas *evasCanvas, Rectangle dimensions, Color color)
{
ASSERT(!(dimensions.size.width && dimensions.size.height), "Unhandled line animation");
dimensions.position.y -= DEFAULT_LINE_THICKNESS / 2;
dimensions.size.width += DEFAULT_LINE_THICKNESS;
dimensions.size.height += DEFAULT_LINE_THICKNESS;
- return createAndShowRectangle(evasCanvas, dimensions);
+ return createAndShowRectangle(evasCanvas, dimensions, color);
}
- evas::CompositeLine drawCompositeLine(Evas *evasCanvas, Rectangle dimensions)
+ evas::CompositeLine drawCompositeLine(Evas *evasCanvas, Rectangle dimensions, Color color)
{
- return {createAndShowThickLine(evasCanvas, dimensions), createAndShowThinLine(evasCanvas, dimensions)};
+ return {createAndShowThickLine(evasCanvas, dimensions, color), createAndShowThinLine(evasCanvas, dimensions, color.invert())};
}
}
-evas::Shape evas::drawSolidLine(Evas *evasCanvas, Rectangle dimensions)
+evas::Shape evas::drawSolidLine(Evas *evasCanvas, Rectangle dimensions, Color color)
{
evas::Shape line;
- line.push_back(drawCompositeLine(evasCanvas, dimensions));
+ line.push_back(drawCompositeLine(evasCanvas, dimensions, color));
return line;
}
-evas::Shape evas::drawDashedLine(Evas *evasCanvas, Rectangle dimensions)
+evas::Shape evas::drawDashedLine(Evas *evasCanvas, Rectangle dimensions, Color color)
{
Shape line;
if (dimensions.size.height == 0) { //horizontal line
for (auto x = dimensions.position.x; x + DASHED_LINE_LENGTH <= dimensions.position.x + dimensions.size.width;
x += 2 * (DASHED_LINE_LENGTH + DEFAULT_LINE_THICKNESS)) {
- line.push_back(drawCompositeLine(evasCanvas, {{x, dimensions.position.y}, {DASHED_LINE_LENGTH, 0}}));
+ line.push_back(drawCompositeLine(evasCanvas, {{x, dimensions.position.y}, {DASHED_LINE_LENGTH, 0}}, color));
}
} else if (dimensions.size.width == 0) { //vertical line
for (auto y = dimensions.position.y; y + DASHED_LINE_LENGTH <= dimensions.position.y + dimensions.size.height;
y += 2 * (DASHED_LINE_LENGTH + DEFAULT_LINE_THICKNESS)) {
- line.push_back(drawCompositeLine(evasCanvas, {{dimensions.position.x, y}, {0, DASHED_LINE_LENGTH}}));
+ line.push_back(drawCompositeLine(evasCanvas, {{dimensions.position.x, y}, {0, DASHED_LINE_LENGTH}}, color));
}
} else {
ASSERT(0, "Unhandled line animation");
}
}
-evas::Shape evas::drawSolidFrame(Evas *evasCanvas, Rectangle dimensions)
+evas::Shape evas::drawSolidFrame(Evas *evasCanvas, Rectangle dimensions, Color color)
{
Shape frame;
- frame.push_back(drawCompositeLine(evasCanvas, {dimensions.position, {dimensions.size.width, 0}}));
+ frame.push_back(drawCompositeLine(evasCanvas, {dimensions.position, {dimensions.size.width, 0}}, color));
frame.push_back(drawCompositeLine(evasCanvas,
- {{dimensions.position.x, dimensions.position.y + dimensions.size.height}, {dimensions.size.width, 0}}));
- frame.push_back(drawCompositeLine(evasCanvas, {dimensions.position, {0, dimensions.size.height}}));
+ {{dimensions.position.x, dimensions.position.y + dimensions.size.height}, {dimensions.size.width, 0}}, color));
+ frame.push_back(drawCompositeLine(evasCanvas, {dimensions.position, {0, dimensions.size.height}}, color));
frame.push_back(drawCompositeLine(evasCanvas,
- {{dimensions.position.x + dimensions.size.width, dimensions.position.y}, {0, dimensions.size.height}}));
+ {{dimensions.position.x + dimensions.size.width, dimensions.position.y}, {0, dimensions.size.height}}, color));
formatShapeLayout(frame);
return frame;
}
-evas::Shape evas::drawDashedFrame(Evas *evasCanvas, Rectangle dimensions)
+evas::Shape evas::drawDashedFrame(Evas *evasCanvas, Rectangle dimensions, Color color)
{
Shape frame;
for (auto x = dimensions.position.x; x + DASHED_LINE_LENGTH <= dimensions.position.x + dimensions.size.width;
x += 2 * (DASHED_LINE_LENGTH + DEFAULT_LINE_THICKNESS)) {
- frame.push_back(drawCompositeLine(evasCanvas, {{x, dimensions.position.y}, {DASHED_LINE_LENGTH, 0}}));
+ frame.push_back(drawCompositeLine(evasCanvas, {{x, dimensions.position.y}, {DASHED_LINE_LENGTH, 0}}, color));
frame.push_back(drawCompositeLine(evasCanvas,
- {{x, dimensions.position.y + dimensions.size.height}, {DASHED_LINE_LENGTH, 0}}));
+ {{x, dimensions.position.y + dimensions.size.height}, {DASHED_LINE_LENGTH, 0}}, color));
}
for (auto y = dimensions.position.y; y + DASHED_LINE_LENGTH <= dimensions.position.y + dimensions.size.height;
y += 2 * (DASHED_LINE_LENGTH + DEFAULT_LINE_THICKNESS)) {
- frame.push_back(drawCompositeLine(evasCanvas, {{dimensions.position.x, y}, {0, DASHED_LINE_LENGTH}}));
+ frame.push_back(drawCompositeLine(evasCanvas, {{dimensions.position.x, y}, {0, DASHED_LINE_LENGTH}}, color));
frame.push_back(drawCompositeLine(evasCanvas,
- {{dimensions.position.x + dimensions.size.width, y}, {0, DASHED_LINE_LENGTH}}));
+ {{dimensions.position.x + dimensions.size.width, y}, {0, DASHED_LINE_LENGTH}}, color));
}
formatShapeLayout(frame);
}
};
+class Color
+{
+public:
+ Color(int r, int g, int b, int a = {});
+
+ int getR() const;
+ int getG() const;
+ int getB() const;
+ int getA() const;
+
+ int toRGBAInt() const;
+ Color invert() const;
+ static Color fromRGBA(int rgba);
+ static Color fromABGR(int abgr);
+
+private:
+ int r;
+ int g;
+ int b;
+ int a;
+};
+
namespace evas
{
struct ObjectDeleter {
using Transit = std::unique_ptr<Elm_Transit, TransitDeleter>;
- Shape drawSolidLine(Evas *evasCanvas, Rectangle dimensions);
- Shape drawDashedLine(Evas *evasCanvas, Rectangle dimensions);
- Shape drawSolidFrame(Evas *evasCanvas, Rectangle dimensions);
- Shape drawDashedFrame(Evas *evasCanvas, Rectangle dimensions);
+ Shape drawSolidLine(Evas *evasCanvas, Rectangle dimensions, Color color);
+ Shape drawDashedLine(Evas *evasCanvas, Rectangle dimensions, Color color);
+ Shape drawSolidFrame(Evas *evasCanvas, Rectangle dimensions, Color color);
+ Shape drawDashedFrame(Evas *evasCanvas, Rectangle dimensions, Color color);
}
#endif
std::pair<evas::Transit, evas::Shape> PointScannerImpl::createAnimation(Rectangle dimensions, Point translation)
{
auto evasCanvas = evas_object_evas_get(Singleton<UniversalSwitch>::instance().getMainWindow()->getHandler());
- auto solidLine = evas::drawSolidLine(evasCanvas, dimensions);
+ auto solidLine = evas::drawSolidLine(evasCanvas, dimensions, properties.getColor());
auto transit = runTransit(solidLine, translation);
return {std::move(transit), std::move(solidLine)};
}
auto scanningField = properties.getScanningField();
dashedLine = evas::drawDashedLine(evasCanvas,
- {{scanningField.position.x, intersectionPoint.y}, {scanningField.size.width, 0}});
+ {{scanningField.position.x, intersectionPoint.y}, {scanningField.size.width, 0}}, properties.getColor());
}
void PointScannerImpl::tearDownDashedLine()
auto scanningField = properties.getScanningField();
horizontalLine = evas::drawSolidLine(evasCanvas,
- {{scanningField.position.x, intersectionPoint.y}, {scanningField.size.width, 0}});
+ {{scanningField.position.x, intersectionPoint.y}, {scanningField.size.width, 0}}, properties.getColor());
}
void PointScannerImpl::onInactivity()
void selectNewElement(NavigationState);
- void drawFrame(Rectangle dimensions, NavigationInterface::BoxPositionMode mode);
+ void drawFrame(Rectangle dimensions, NavigationInterface::BoxPositionMode mode, Color color);
void forceRender();
void eraseFrame();
}
drawFrame(pos, currentNavState.childIndex ?
- NavigationInterface::BoxPositionMode::NORMAL : NavigationInterface::BoxPositionMode::DASHED);
+ NavigationInterface::BoxPositionMode::NORMAL : NavigationInterface::BoxPositionMode::DASHED, properties.getColor());
}
void RowScannerImpl::clearCursor()
inactiveLoopCounter = 0;
}
-void RowScannerImpl::drawFrame(Rectangle dimensions, NavigationInterface::BoxPositionMode mode)
+void RowScannerImpl::drawFrame(Rectangle dimensions, NavigationInterface::BoxPositionMode mode, Color color)
{
if (mode == NavigationInterface::BoxPositionMode::NONE ||
(lastFrameDimensions != dimensions && lastFrameMode != mode)) {
auto evasCanvas = evas_object_evas_get(Singleton<UniversalSwitch>::instance().getMainWindow()->getHandler());
if (mode == NavigationInterface::BoxPositionMode::NORMAL)
- frame = evas::drawSolidFrame(evasCanvas, dimensions);
+ frame = evas::drawSolidFrame(evasCanvas, dimensions, color);
else
- frame = evas::drawDashedFrame(evasCanvas, dimensions);
+ frame = evas::drawDashedFrame(evasCanvas, dimensions, color);
forceRender();
}
return scanningField;
}
+Color ScanningProperties::getColor() const
+{
+ return color;
+}
+
void ScanningProperties::readScanningProperties()
{
registerAndSet(VCONF_KEY_AUTO_SCAN_ENABLED, true, &ScanningProperties::setCachedAutoScanEnabled);
registerAndSet(VCONF_KEY_SCAN_PT_SPEED, DEFAULT_SPEED, &ScanningProperties::setCachedSpeed);
registerAndSet(VCONF_KEY_PAUSE_ON_FIRST_ELEMENT_ENABLED, true, &ScanningProperties::setCachedPauseOnFirstElementEnabled);
registerAndSet(VCONF_KEY_PAUSE_ON_FIRST_ELEMENT_TIME, DEFAULT_TIME, &ScanningProperties::setCachedPauseOnFirstElementTime);
+ registerAndSet(VCONF_KEY_FEEDBACK_CURSOR_COLOR, DEFAULT_COLOR, &ScanningProperties::setCachedColor);
}
template<class T, class SetterMethod>
DEBUG("passed: %lf, current: %lf", time, pauseOnFirstElementTime);
ASSERT(pauseOnFirstElementTime >= 0);
}
+
+void ScanningProperties::setCachedColor(int value)
+{
+ color = Color::fromABGR(value);
+ DEBUG("color: %#010x", color);
+}
\ No newline at end of file
int getSpeed() const;
double getPauseOnFirstElementTime() const;
Rectangle getScanningField() const;
+ Color getColor() const;
void setEscapeFrameEnabled(bool state);
void setScanningField(const Rectangle &rect);
void setCachedSpeed(int velocity);
void setCachedPauseOnFirstElementEnabled(bool state);
void setCachedPauseOnFirstElementTime(double time);
+ void setCachedColor(int value);
std::vector<VConfInterface::CallbackHandle> vconfHandles;
bool pauseOnFirstElementEnabled = true;
double pauseOnFirstElementTime = 0.0;
Rectangle scanningField;
+ Color color = Color::fromABGR(DEFAULT_COLOR);
bool escapeFrameEnabled = false;
constexpr static int DEFAULT_SPEED = 30;
constexpr static double DEFAULT_TIME = 2.0;
constexpr static int DEFAULT_LOOP_LIMIT_TO_INACTION = 5;
+ constexpr static int DEFAULT_COLOR = 0xff00ff00;
};
#endif
#define VCONF_KEY_TEXT_EDITION_MODE VCONF_PROJECT_PREFIX "TEXT_EDITION_MODE"
+#define VCONF_KEY_FEEDBACK_CURSOR_COLOR VCONF_PROJECT_PREFIX "FEEDBACK_CURSOR_COLOR"
+
#define VCONF_KEY_AUTO_ROTATE "db/setting/auto_rotate_screen"
#define VCONF_KEY_SOUND_ENABLED "db/setting/sound/sound_on"
return {};
};
variables["find_by_name"] = EvaluationValueFunction{ [&](std::string name, std::vector<int> roles, std::vector<int> states) -> EvaluationValue_ {
- auto root = getVisibleRoot();
- if (!root) throw EvaluationFailure{} << "no visible root (context changed didn't happen)";
- ASSERT(root->getObject());
- Monitor<BatchValueOrError<std::vector<std::shared_ptr<UIElement>>>> monitor;
+ auto root = getVisibleRoot();
+ if (!root) throw EvaluationFailure{} << "no visible root (context changed didn't happen)";
+ ASSERT(root->getObject());
+ Monitor<BatchValueOrError<std::vector<std::shared_ptr<UIElement>>>> monitor;
- return executeOnMainThread([&]()
- {
- getAllObjects(root->getObject(), wrap(monitor, [ = ](DBus::ValueOrError<std::vector<AtspiAccessiblePtr>> allElements) {
- findByName(std::get<0>(allElements), name, wrap(monitor, [ = ](DBus::ValueOrError<std::vector<AtspiAccessiblePtr>> elements) {
- auto &elems = std::get<0>(elements);
- makeUIElements(std::move(elems), wrap(monitor, [ = ](DBus::ValueOrError<std::vector<std::shared_ptr<UIElement>>> uiElems) {
- auto h = monitor.lock();
- h->setValue(std::move(std::get<0>(uiElems)));
+ return executeOnMainThread([&]()
+ {
+ getAllObjects(root->getObject(), wrap(monitor, [ = ](DBus::ValueOrError<std::vector<AtspiAccessiblePtr>> allElements) {
+ findByName(std::get<0>(allElements), name, wrap(monitor, [ = ](DBus::ValueOrError<std::vector<AtspiAccessiblePtr>> elements) {
+ auto &elems = std::get<0>(elements);
+ makeUIElements(std::move(elems), wrap(monitor, [ = ](DBus::ValueOrError<std::vector<std::shared_ptr<UIElement>>> uiElems) {
+ auto h = monitor.lock();
+ h->setValue(std::move(std::get<0>(uiElems)));
+ }));
}));
- }));
- }), std::move(roles), std::move(states));
- }, monitor);
- }, { { "name" }, { "roles", EvaluationValueSet() }, { "states", EvaluationValueSet() } } };
+ }), std::move(roles), std::move(states));
+ }, monitor);
+ }, { { "name" }, { "roles", EvaluationValueSet() }, { "states", EvaluationValueSet() } } };
}
void insertWaits()
std::string pattern;
bool success = false;
- void join() override {
+ void join() override
+ {
if (success) return;
auto h = self->ttsInfo.lock();
- success = h.waitForCondition(untilMoment, [&]()
- {
+ success = h.waitForCondition(untilMoment, [&]() {
return h->mode == TTSInfo::Mode::found;
});
- if (!success)
- {
+ if (!success) {
h->mode = TTSInfo::Mode::ignore;
throw EvaluationFailure{} << "wait for dlog ('" << pattern << "'): operation timeouted";
}
h->mode = TTSInfo::Mode::ignore;
}
- bool isSatisfied() override {
+ bool isSatisfied() override
+ {
if (success) return true;
auto h = self->ttsInfo.lock();
return success = (h->mode == TTSInfo::Mode::found);
}
};
-
+
auto waitTTSImpl = [&](std::string pattern) -> EvaluationValue_ {
std::regex regex;
if (!pattern.empty())
std::string currentRootName;
bool success = false, searchForAnyChange = false;
- void join() override {
+ void join() override
+ {
if (success) return;
auto h = self->contextInfo.lock();
- success = h.waitForCondition(untilMoment, [&]()
- {
+ success = h.waitForCondition(untilMoment, [&]() {
return
- (searchForAnyChange && currentRootName != h->rootName) ||
- (!searchForAnyChange && h->rootName == name);
+ (searchForAnyChange && currentRootName != h->rootName) ||
+ (!searchForAnyChange && h->rootName == name);
});
- if (!success)
- {
+ if (!success) {
throw EvaluationFailure{} << "wait for gui ('" << name << "'): operation timeouted, " <<
- "current root name is '" << h->rootName << "'";
+ "current root name is '" << h->rootName << "'";
}
}
- bool isSatisfied() override {
+ bool isSatisfied() override
+ {
if (success) return true;
auto h = self->contextInfo.lock();
return success = (h->rootName == name);
*outputPtr << os.str() << "\n\n";
}
auto exec = std::make_unique<TestExecutor>(*outputPtr);
- auto threadFunc = [result = std::move(result), exec = std::move(exec), outputPtr = std::move(outputPtr), dlog = std::move(dlog) ]() mutable
+ auto threadFunc = [result = std::move(result), exec = std::move(exec), outputPtr = std::move(outputPtr), dlog = std::move(dlog) ]() mutable {
+ EvaluationContext ec(*exec);
+ exec->outputStream() << "waiting for context change...\n";
+ auto until = std::chrono::high_resolution_clock::now() + std::chrono::seconds{ 2 };
+ bool hasContext = false;
{
- EvaluationContext ec(*exec);
- exec->outputStream() << "waiting for context change...\n";
- auto until = std::chrono::high_resolution_clock::now() + std::chrono::seconds{ 2 };
- bool hasContext = false;
- {
- auto h = exec->contextInfo.lock();
- hasContext = h.waitForCondition(until, [&]()
- {
- // h->root is pointer to root of visible at-spi hierarchy
- // if it's null, then either context building machinery didn't yet finish,
- // there's nothing visible to show or something went wrong
- // here we wait for it to be non-null (context finished constructing)
- // if it timeouts - something went wrong, so we bail out with an error
- return bool(h->root);
- });
- }
- if (hasContext)
+ auto h = exec->contextInfo.lock();
+ hasContext = h.waitForCondition(until, [&]()
{
- auto ttsMainRegex = std::regex {
- "^D/SCREEN-READER[^>]*?> READ COMMAND PARAMS, TEXT: (.*?), DISCARDABLE: 0",
- std::regex_constants::optimize | std::regex_constants::ECMAScript
- };
- auto ttsDlogHandler = dlog.registerCallback([&exec, ttsMainRegex = std::move(ttsMainRegex)](const std::string & txt) {
- auto h = exec->ttsInfo.lock();
- if (h->mode == TestExecutor::TTSInfo::Mode::search) {
- if (!h->searchLine) {
- h->mode = TestExecutor::TTSInfo::Mode::found;
- } else {
- std::smatch result;
- if (std::regex_search(txt, result, ttsMainRegex)) {
- auto sub = result[1].str();
- if (std::regex_search(sub, *h->searchLine))
- h->mode = TestExecutor::TTSInfo::Mode::found;
- }
+ // h->root is pointer to root of visible at-spi hierarchy
+ // if it's null, then either context building machinery didn't yet finish,
+ // there's nothing visible to show or something went wrong
+ // here we wait for it to be non-null (context finished constructing)
+ // if it timeouts - something went wrong, so we bail out with an error
+ return bool(h->root);
+ });
+ }
+ if (hasContext)
+ {
+ auto ttsMainRegex = std::regex {
+ "^D/SCREEN-READER[^>]*?> READ COMMAND PARAMS, TEXT: (.*?), DISCARDABLE: 0",
+ std::regex_constants::optimize | std::regex_constants::ECMAScript
+ };
+ auto ttsDlogHandler = dlog.registerCallback([&exec, ttsMainRegex = std::move(ttsMainRegex)](const std::string & txt) {
+ auto h = exec->ttsInfo.lock();
+ if (h->mode == TestExecutor::TTSInfo::Mode::search) {
+ if (!h->searchLine) {
+ h->mode = TestExecutor::TTSInfo::Mode::found;
+ } else {
+ std::smatch result;
+ if (std::regex_search(txt, result, ttsMainRegex)) {
+ auto sub = result[1].str();
+ if (std::regex_search(sub, *h->searchLine))
+ h->mode = TestExecutor::TTSInfo::Mode::found;
}
}
- });
- exec->outputStream() << "evaluation started\n";
- try {
- result->evaluate();
- exec->outputStream() << "evaluation successed\n";
- } catch (EvaluationFailure &e) {
- if (e.hasLocation())
- exec->outputStream() << e.location().toString() << ": ";
- exec->outputStream() << e.message() << "\nevaluation failed\n";
- } catch (...) {
- exec->outputStream() << "unhandled exception\nevaluation failed\n";
}
- } else
- {
- exec->outputStream() << "timeouted\n";
- DEBUG("timeouted, when waiting for context change");
- }
- outputPtr->flush();
- executeOnMainThread([]()
- {
- ecore_main_loop_quit();
});
- DEBUG("done batch");
- };
+ exec->outputStream() << "evaluation started\n";
+ try {
+ result->evaluate();
+ exec->outputStream() << "evaluation successed\n";
+ } catch (EvaluationFailure &e) {
+ if (e.hasLocation())
+ exec->outputStream() << e.location().toString() << ": ";
+ exec->outputStream() << e.message() << "\nevaluation failed\n";
+ } catch (...) {
+ exec->outputStream() << "unhandled exception\nevaluation failed\n";
+ }
+ } else
+ {
+ exec->outputStream() << "timeouted\n";
+ DEBUG("timeouted, when waiting for context change");
+ }
+ outputPtr->flush();
+ executeOnMainThread([]()
+ {
+ ecore_main_loop_quit();
+ });
+ DEBUG("done batch");
+ };
return std::thread { std::move(threadFunc) };
}
/**
* @brief Interface class for providing external world functionality (at-spi queries and so on)
- *
+ *
* User should reimplement all methods. Default implementations will throw "not implemented" exceptions.
*/
struct ExecutorInterface {
/**
* @brief Finds variable by name
- *
+ *
* Fallback method, when variable is not found in any script's scopes.
* This is sort of global variables implementation.
* Note, while variable found by this found can't be overwritten (can be updated)
/**
* @brief Finds object on screen by position
- *
+ *
* Implementation is expected to return object "closest" to user at position
* given as argument. Batch implementation queries visible at-spi objects
* for their position and "walk" all objects in tree-like fashion, until
/**
* @brief Finds object on screen by name
- *
+ *
* Implementation is expected to return object with at-spi name
* exactly matching one given, but only if there's only one. Otherwise an
* exception should be raised.
/**
* @brief Returns at-spi object, which is root of visible at-spi elements
- *
+ *
* Visible root is expected to be some descendant of application's root element.
*/
virtual std::shared_ptr<UIElement> getVisibleRoot() = 0;
/**
* @brief Returns stream, which should be used for writing any kind of output
- *
+ *
* Note, that this stream should be only used from batch's thread.
* Stream might as well point to /dev/null.
* There's only single stream for all kinds of output, debug or not.
};
/**
- * @brief Wrapper class containing batch script value
- *
+ * @brief Wrapper class containing batch script value
+ *
* This is a wrapper, contaiing a value from batch script. It can hold any type of supported value.
* Any functionality requested from object of this class will be redirected to correct implementation
* method in the EvaluationValueBase interface. Classes inheriting from EvaluationValueBase are classes
* implementing values of all supported types (see EvaluationValue***.cpp files). Those classes
* override virtual methods of the EvaluationValueBase interface to add required functionality.
- *
+ *
* EvaluationValue_ supports implicit cast from C++ types, which can be used in batch script (for example
- * chars shorts and ints can be converted to EvaluationValueInteger, std::string can be converted to
+ * chars shorts and ints can be converted to EvaluationValueInteger, std::string can be converted to
* EvaluationValueString and so on).
*/
class EvaluationValue_
e << ", when converting " << (I + 1) << " argument";
throw;
}
- }
- else {
+ } else {
Converter < I + 1, S >::convertSingleArgumentByIndex(dst, arg, index);
}
}
class Args
{
public:
- Args(const std::vector<EvaluationValue_> &args,
- const std::unordered_map<std::string, EvaluationValue_> &keyArgs = {}) : args(args), keyArgs(keyArgs) { }
+ Args(const std::vector<EvaluationValue_> &args,
+ const std::unordered_map<std::string, EvaluationValue_> &keyArgs = {}) : args(args), keyArgs(keyArgs) { }
bool empty() const
{
{
return args[index];
}
- const std::unordered_map<std::string, EvaluationValue_> &keywords() const { return keyArgs; }
- bool hasKeywords() const { return !keyArgs.empty(); }
+ const std::unordered_map<std::string, EvaluationValue_> &keywords() const
+ {
+ return keyArgs;
+ }
+ bool hasKeywords() const
+ {
+ return !keyArgs.empty();
+ }
private:
const std::vector<EvaluationValue_> &args;
const std::unordered_map<std::string, EvaluationValue_> &keyArgs;
};
- using Type = std::function<EvaluationValue_(const Args&)>;
-
+ using Type = std::function<EvaluationValue_(const Args &)>;
+
EvaluationValueFunction() = default;
template <typename T, typename ARGS_TUPLE = typename detail::get_args_as_tuple_from_lambda<T>::type,
typename = typename std::enable_if<detail::are_args_allowed_evaluation_value_from_tuple<ARGS_TUPLE>::value>::type>
std::unordered_map<std::string, size_t> keywordIndexes;
size_t argIndex = 0;
- for(auto &a : argDescriptions) {
+ for (auto &a : argDescriptions) {
if (!a.getName().empty()) {
auto it = keywordIndexes.insert({ a.getName(), argIndex });
ASSERT(it.second); // every arg name must be unique
++argIndex;
}
return [f = std::move(f), defaultArguments = std::move(defaultArguments), firstDefaultArgIndex, keywordIndexes = std::move(keywordIndexes)]
- (const Args &sourceArgs) -> EvaluationValue_ {
+ (const Args & sourceArgs) -> EvaluationValue_ {
ARGS_TUPLE args;
- if (!sourceArgs.hasKeywords()) {
+ if (!sourceArgs.hasKeywords())
+ {
DEBUG(".");
validateArgumentCount(sourceArgs.size(), firstDefaultArgIndex, expectedArgCount);
DEBUG(".");
detail::Converter<0, expectedArgCount>::convert(args, sourceArgs, firstDefaultArgIndex, defaultArguments);
DEBUG(".");
- }
- else {
+ } else
+ {
DEBUG(".");
std::vector<bool> used(expectedArgCount, false);
DEBUG("%d", (int)sourceArgs.size());
detail::Converter<0, expectedArgCount>::convert(args, sourceArgs, firstDefaultArgIndex, defaultArguments, sourceArgs.size());
DEBUG(".");
- for(auto i = 0u; i < sourceArgs.size(); ++i) used[i] = true;
+ for (auto i = 0u; i < sourceArgs.size(); ++i) used[i] = true;
DEBUG(".");
- for(auto &val : sourceArgs.keywords()) {
+ for (auto &val : sourceArgs.keywords()) {
DEBUG(".");
auto it = keywordIndexes.find(val.first);
if (it == keywordIndexes.end()) {
DEBUG(".");
}
DEBUG("%d %d", (int)firstDefaultArgIndex, (int)expectedArgCount);
- for(auto i = 0u; i < firstDefaultArgIndex; ++i) {
+ for (auto i = 0u; i < firstDefaultArgIndex; ++i) {
if (!used[i]) {
DEBUG(".");
throw EvaluationFailure{} << "argument " << (i + 1) << " not set";
}
}
DEBUG(".");
- for(auto i = firstDefaultArgIndex; i < expectedArgCount; ++i) {
+ for (auto i = firstDefaultArgIndex; i < expectedArgCount; ++i) {
DEBUG(".");
if (!used[i]) {
DEBUG(".");
void writeToStream(std::ostream &os) const override
{
- os << "<" <<
- EvaluationContext::getCurrentEvaluationContext().executionInterface().getUIElementUniqueId(value) <<
- ">";
+ os << "<" <<
+ EvaluationContext::getCurrentEvaluationContext().executionInterface().getUIElementUniqueId(value) <<
+ ">";
}
size_t oper_hash() override
{
return val;
}
EvaluationValuePtr oper_index_set(const EvaluationValuePtr &from, const EvaluationValuePtr &to, const EvaluationValuePtr &val) override
- {
+ {
if (!val->isVector())
return EvaluationValueBase::oper_index_set(from, to, val);
struct CallOnExit {
std::function<void()> func;
CallOnExit(std::function<void()> func) : func(std::move(func)) { }
- ~CallOnExit() { func(); }
- };
+ ~CallOnExit()
+ {
+ func();
+ }
+ };
EvaluationDepthCountManager countManager;
if (!debugInterface) {
try {
return f();
- } catch(EvaluationFailure &ev) {
+ } catch (EvaluationFailure &ev) {
ev.setLocationIfMissing(loc);
throw;
}
}
std::string indent(static_cast<size_t>(evaluationDepth * 2), ' ');
try {
- CallOnExit call{ [&]() { debugInterface->write(indent + "leaving " + debugId); } };
+ CallOnExit call{ [&]()
+ {
+ debugInterface->write(indent + "leaving " + debugId);
+ } };
debugInterface->write(indent + "entering " + debugId);
return f();
- } catch(EvaluationFailure &ev) {
+ } catch (EvaluationFailure &ev) {
ev.setLocationIfMissing(loc);
debugInterface->write(indent + "exception " + debugId + " (" + ev.what() + "), leaving");
throw;
EvaluationValue_ ExpressionEvaluator::evaluate() const
{
- return evaluateHelper(std::to_string(getDebugId()), location(), [&]() { return evaluateImpl(); });
+ return evaluateHelper(std::to_string(getDebugId()), location(), [&]() {
+ return evaluateImpl();
+ });
}
void StatementEvaluator::evaluate() const
{
- return evaluateHelper(std::to_string(getDebugId()), location(), [&]() { return evaluateImpl(); });
+ return evaluateHelper(std::to_string(getDebugId()), location(), [&]() {
+ return evaluateImpl();
+ });
}
IdentifierEvaluator::IdentifierEvaluator(TokenLocation tokenLocation, std::string identifier) :
for (auto &arg : args) {
values.push_back(arg->evaluate());
}
- for(auto &it : keywordArgs) {
+ for (auto &it : keywordArgs) {
keywordValues[it.first] = it.second->evaluate();
}
return function->evaluate()(values, keywordValues);
/**
* @brief Type representing group of statements, with wait conditions applied to them
- *
+ *
* exec represents statement (or group of statemenets), to be executed and waited for.
* waits are wait conditions - whatever those wait for must happen at the moment
* WaitEvaluator starts evaluating (or later). This statement will block
index += 2;
auto e = parseExpr();
if (!e) return false;
- it.first->second = std::move(e);
- }
- else {
+ it.first->second = std::move(e);
+ } else {
if (alreadyKeywords) {
error("positional argument after keyword argument is not allowed");
return false;
$VCONFTOOL bool "${VCONF_PROJECT_PREFIX}AUTO_TAP_KBD_ENABLED" 0
-$VCONFTOOL int "${VCONF_PROJECT_PREFIX}FEEDBACK_CURSOR_COLOR" 0
+$VCONFTOOL int "${VCONF_PROJECT_PREFIX}FEEDBACK_CURSOR_COLOR" -16711936
$VCONFTOOL bool "${VCONF_PROJECT_PREFIX}FEEDBACK_SOUND_ENABLED" 1
$VCONFTOOL double "${VCONF_PROJECT_PREFIX}FEEDBACK_SOUND_VOLUME" 1.0