Merge "Prevents writing array uniforms with out-of-bound indices and accidental overw...
[platform/core/uifw/dali-adaptor.git] / dali / internal / accessibility / bridge / bridge-collection.cpp
index 6795674..2011130 100644 (file)
@@ -20,7 +20,6 @@
 
 // EXTERNAL INCLUDES
 #include <algorithm>
-#include <iostream>
 #include <unordered_set>
 #include <vector>
 
@@ -46,21 +45,16 @@ enum class AtspiCollection
 
 void BridgeCollection::RegisterInterfaces()
 {
-  DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceCollection};
+  DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::COLLECTION)};
   AddFunctionToInterface(desc, "GetMatches", &BridgeCollection::GetMatches);
+  AddFunctionToInterface(desc, "GetMatchesInMatches", &BridgeCollection::GetMatchesInMatches);
+
   mDbusServer.addInterface("/", desc, true);
 }
 
 Collection* BridgeCollection::FindSelf() const
 {
-  auto self = BridgeBase::FindSelf();
-  assert(self);
-  auto collectionInterface = dynamic_cast<Collection*>(self);
-  if(!collectionInterface)
-  {
-    throw std::domain_error{"object " + self->GetAddress().ToString() + " doesn't have Collection interface"};
-  }
-  return collectionInterface;
+  return FindCurrentObjectWithInterface<Dali::Accessibility::AtspiInterface::COLLECTION>();
 }
 
 /**
@@ -128,7 +122,7 @@ struct BridgeCollection::Comparer
     void Update(Accessible* obj)
     {
       mObject.clear();
-      for(auto& interface : obj->GetInterfaces())
+      for(auto& interface : obj->GetInterfacesAsStrings())
       {
         mObject.insert(std::move(interface));
       }
@@ -220,7 +214,7 @@ struct BridgeCollection::Comparer
    */
   struct ComparerRoles
   {
-    using Roles = BitSets<4, Role>;
+    using Roles = EnumBitSet<Role, Role::MAX_COUNT>;
 
     Roles mRequested;
     Roles mObject;
@@ -457,6 +451,17 @@ struct BridgeCollection::Comparer
            CompareFunc(mState, obj);
   }
 
+  bool IsShowing(Accessible* obj)
+  {
+    if (mState.mMode == Mode::NONE) return true;
+    mState.Update(obj);
+    if (mState.IsRequestEmpty() || mState.IsObjectEmpty()) return true;
+    if (!mState.mRequested[State::SHOWING] ) return true;
+    if (mState.mObject[State::SHOWING]) return true;
+
+    return false;
+  }
+
   ComparerInterfaces mInterface;
   ComparerAttributes mAttribute;
   ComparerRoles      mRole;
@@ -474,6 +479,16 @@ void BridgeCollection::VisitNodes(Accessible* obj, std::vector<Accessible*>& res
   if(comparer(obj))
   {
     result.emplace_back(obj);
+    // the code below will never return for maxCount equal 0
+    if(result.size() == maxCount)
+    {
+      return;
+    }
+  }
+
+  if (!comparer.IsShowing(obj))
+  {
+    return;
   }
 
   for(auto i = 0u; i < obj->GetChildCount(); ++i)
@@ -485,7 +500,7 @@ void BridgeCollection::VisitNodes(Accessible* obj, std::vector<Accessible*>& res
 DBus::ValueOrError<std::vector<Accessible*> > BridgeCollection::GetMatches(MatchRule rule, uint32_t sortBy, int32_t count, bool traverse)
 {
   std::vector<Accessible*> res;
-  auto                     self    = BridgeBase::FindSelf();
+  auto                     self    = BridgeBase::FindCurrentObject();
   auto                     matcher = Comparer{&rule};
   VisitNodes(self, res, matcher, count);
 
@@ -511,3 +526,44 @@ DBus::ValueOrError<std::vector<Accessible*> > BridgeCollection::GetMatches(Match
 
   return res;
 }
+
+DBus::ValueOrError<std::vector<Accessible*> > BridgeCollection::GetMatchesInMatches(MatchRule firstRule, MatchRule secondRule, uint32_t sortBy, int32_t firstCount, int32_t secondCount, bool traverse)
+{
+  std::vector<Accessible*> res;
+  std::vector<Accessible*> firstRes;
+  std::vector<Accessible*> secondRes;
+  auto                     self          = BridgeBase::FindCurrentObject();
+  auto                     firstMatcher  = Comparer{&firstRule};
+  auto                     secondMatcher = Comparer{&secondRule};
+  VisitNodes(self, firstRes, firstMatcher, firstCount);
+
+  for (auto &obj : firstRes)
+  {
+    VisitNodes(obj, secondRes, secondMatcher, secondCount);
+
+    res.insert(res.end(), secondRes.begin(), secondRes.end());
+    secondRes.clear();
+  }
+
+  switch(static_cast<SortOrder>(sortBy))
+  {
+    case SortOrder::CANONICAL:
+    {
+      break;
+    }
+
+    case SortOrder::REVERSE_CANONICAL:
+    {
+      std::reverse(res.begin(), res.end());
+      break;
+    }
+
+    default:
+    {
+      throw std::domain_error{"unsupported sorting order"};
+    }
+      //TODO: other cases
+  }
+
+  return res;
+}