Ver Fonte

[add] equivalence map between A and B's parts with JSonElement matching or close enough
[add][WIP] write A and B content, but stop at back-to-matching (doing some tests, not working atm, but it'll just be a loop to add. Theorically.)

B Thibault há 9 anos atrás
pai
commit
ddcf0f6055

+ 4 - 2
include/curseSplitOutput.hh

@@ -17,8 +17,8 @@ typedef struct
     std::list<const JSonElement*> searchResults;
     unsigned int scrollTop;
     t_Cursor cursor;
-    std::stack<JSonContainer::const_iterator> pos;
-    bool selectFound, selectIsLast;
+    std::stack<const JSonElement *> parentsIterators;
+    bool selectFound, selectIsLast, inAddOrDeletion;
 } t_subWindow;
 
 class CurseSplitOutput: public CurseOutput
@@ -95,6 +95,8 @@ class CurseSplitOutput: public CurseOutput
         **/
         unsigned short nbInputs, selectedWin, workingWin;
 
+        class reachNext {};
+
         // TODO t_subWindow &workingSubwin, &selectedSubwin ??
 };
 

+ 15 - 1
include/levenshteinMatrice.hpp

@@ -23,6 +23,8 @@ class LevenshteinMatrice_base
         virtual bool areSimilar() const =0;
 
         eLevenshteinOperator get(const JSonElement *) const;
+        virtual std::map<const JSonElement *, const JSonElement *> getEquivalences() const;
+        virtual const JSonElement * getEquivalence(const JSonElement *) const;
 
     public:
         class Builder
@@ -52,13 +54,17 @@ class LevenshteinMatrice_manual: public LevenshteinMatrice_base
 class LevenshteinMatriceWithScore: public LevenshteinMatrice_base
 {
     public:
-        LevenshteinMatriceWithScore(float score);
+        LevenshteinMatriceWithScore(float score, const JSonElement *a, const JSonElement *b);
+
+        std::map<const JSonElement *, const JSonElement *> getEquivalences() const;
+        virtual const JSonElement * getEquivalence(const JSonElement *) const;
 
         size_t result() const;
         bool areSimilar() const;
 
     private:
         bool _result;
+        const JSonElement *equivalentA, *equivalentB;
 };
 
 class LevenshteinMatrice: public LevenshteinMatrice_base
@@ -138,8 +144,11 @@ class LevenshteinMatrice: public LevenshteinMatrice_base
             delete []subMatrice;
         };
 
+        std::map<const JSonElement*, const JSonElement *> getEquivalences() const;
+
         size_t result() const;
         bool areSimilar() const;
+        const JSonElement *getEquivalence(const JSonElement *) const;
 
     private:
         template<typename T>
@@ -171,6 +180,9 @@ class LevenshteinMatrice: public LevenshteinMatrice_base
                     operations[*i] = operations[*j] = op;
                     for (std::pair<const JSonElement *, eLevenshteinOperator> e : subMatrice[_i -1][_j -1]->path())
                         operations[e.first] = e.second;
+                    for (std::pair<const JSonElement *, const JSonElement *> e : (subMatrice[_i -1][_j -1])->getEquivalences())
+                        equivalences[e.first] = e.second;
+                    equivalences[*i] = *j;
                     --i;
                     --j;
                     --_i;
@@ -194,7 +206,9 @@ class LevenshteinMatrice: public LevenshteinMatrice_base
 
     private:
         LevenshteinMatrice();
+
         size_t levenDist;
         float levenRelativeDist;
+        std::map<const JSonElement*, const JSonElement *> equivalences;
 };
 

+ 31 - 8
src/curseSplitOutput.cpp

@@ -198,6 +198,13 @@ void CurseSplitOutput::checkSelection(const JSonElement *item)
 {
     t_subWindow &w = subWindows.at(workingWin);
 
+    if (diffMatrice->getEquivalence(item))
+    {
+        if (w.inAddOrDeletion)
+            throw CurseSplitOutput::reachNext();
+    }
+    else
+        w.inAddOrDeletion = true;
     if (!w.selectFound)
     {
         if (w.selection == item)
@@ -327,6 +334,7 @@ bool CurseSplitOutput::redraw()
     {
         bool result;
 
+        w.inAddOrDeletion = false;
         try {
             //TODO JSonElement by JSonElement instead of file per file
             result = redraw(screenSize, w.root);
@@ -335,13 +343,21 @@ bool CurseSplitOutput::redraw()
         {
             return false;
         }
-        if (!result && !w.selectFound)
+        catch (CurseSplitOutput::reachNext &)
         {
-            w.scrollTop++;
-            return false;
+            ++workingWin;
+            continue;
+        }
+        if (!result)
+        {
+            if (!w.selectFound)
+            {
+                w.scrollTop++;
+                return false;
+            }
+            if (!w.select_down)
+                w.selectIsLast = true;
         }
-        if (!result && !w.select_down)
-            w.selectIsLast = true;
         if (!w.select_down)
         {
             const JSonContainer *pselect = dynamic_cast<const JSonContainer*>(w.selection);
@@ -385,8 +401,13 @@ bool CurseSplitOutput::writeContainer(const t_Cursor &maxSize, const JSonContain
         w.cursor.second += write(w.cursor.first, w.cursor.second, childDelimiter[0], maxSize.first, CurseSplitOutput::getFlag(item));
         if (w.cursor.second > w.scrollTop && (w.cursor.second - w.scrollTop) > maxSize.second -1)
                 return false;
+        w.parentsIterators.push(item);
         if (!writeContent(maxSize, (std::list<JSonElement *> *)item))
+        {
+            w.parentsIterators.pop();
             return false;
+        }
+        w.parentsIterators.pop();
         w.cursor.second += write(w.cursor.first, w.cursor.second, childDelimiter[1], maxSize.first, CurseSplitOutput::getFlag(item));
     }
     return (w.cursor.second < w.scrollTop || (w.cursor.second - w.scrollTop) <= maxSize.second -1);
@@ -506,8 +527,6 @@ bool CurseSplitOutput::writeKey(const std::string &key, const size_t keylen, con
 
 bool CurseSplitOutput::redraw(const t_Cursor &maxSize, JSonElement *item)
 {
-    t_subWindow &w = subWindows.at(workingWin);
-
     checkSelection(item);
     if (dynamic_cast<const JSonContainer*>(item))
     {
@@ -516,6 +535,8 @@ bool CurseSplitOutput::redraw(const t_Cursor &maxSize, JSonElement *item)
     }
     else
     {
+        t_subWindow &w = subWindows.at(workingWin);
+
         w.cursor.second += CurseOutput::write(w.cursor.first, w.cursor.second, item, maxSize.first, CurseSplitOutput::getFlag(item));
         if (w.cursor.second > w.scrollTop && (w.cursor.second - w.scrollTop) > maxSize.second -1)
             return false;
@@ -654,7 +675,9 @@ const OutputFlag CurseSplitOutput::getFlag(const JSonElement *item, const JSonEl
         else if (dr == eLevenshteinOperator::mod)
             res.type(OutputFlag::TYPE_STRING);
     }
-    catch (std::out_of_range &e) {}
+    catch (std::out_of_range &e) {
+        res.type(OutputFlag::SPECIAL_SEARCH);
+    }
     /*
     if (dynamic_cast<const JSonPrimitive<std::string> *>(i))
         res.type(OutputFlag::TYPE_STRING);

+ 41 - 2
src/levenshtein.cpp

@@ -84,7 +84,7 @@ LevenshteinMatrice_base *LevenshteinMatrice_base::Builder::build(const JSonEleme
         if (aIsObject && bIsObject) {
             result *= levenshteinPercent((*(const JSonObjectEntry&)(*a))->stringify(), (*(const JSonObjectEntry&)(*b))->stringify());
         }
-        return new LevenshteinMatriceWithScore(result);
+        return new LevenshteinMatriceWithScore(result, a, b);
     }
 }
 
@@ -93,12 +93,18 @@ eLevenshteinOperator LevenshteinMatrice_base::get(const JSonElement *e) const
     return operations.at(e);
 }
 
+const JSonElement *LevenshteinMatrice_base::getEquivalence(const JSonElement *) const
+{ return nullptr; }
+
 /**
  * base (generic) Matrice
 **/
 const std::map<const JSonElement*, eLevenshteinOperator> LevenshteinMatrice_base::path() const
 { return operations; }
 
+std::map<const JSonElement*, const JSonElement *> LevenshteinMatrice_base::getEquivalences() const
+{ return std::map<const JSonElement*, const JSonElement *>(); }
+
 /**
  * Normal matrice
 **/
@@ -111,6 +117,17 @@ size_t LevenshteinMatrice::result() const
 bool LevenshteinMatrice::areSimilar() const
 { return levenRelativeDist > LEVENSHTEIN_SENSIBILITY; }
 
+const JSonElement *LevenshteinMatrice::getEquivalence(const JSonElement *e) const
+{
+    std::map<const JSonElement *, const JSonElement *>::const_iterator it = equivalences.find(e);
+    if (it == equivalences.cend())
+        return nullptr;
+    return (*it).second;
+}
+
+std::map<const JSonElement*, const JSonElement *> LevenshteinMatrice::getEquivalences() const
+{ return equivalences; }
+
 /**
  * Manual matrice
 **/
@@ -133,9 +150,31 @@ bool LevenshteinMatrice_manual::areSimilar() const
 /**
  * Score matrice
 **/
-LevenshteinMatriceWithScore::LevenshteinMatriceWithScore(float s)
+LevenshteinMatriceWithScore::LevenshteinMatriceWithScore(float s, const JSonElement *a, const JSonElement *b)
 {
     _result = s > LEVENSHTEIN_SENSIBILITY;
+    if (_result)
+    {
+        equivalentA = a;
+        equivalentB = b;
+    }
+    else
+        equivalentA = equivalentB = nullptr;
+}
+
+const JSonElement * LevenshteinMatriceWithScore::getEquivalence(const JSonElement *a) const
+{
+    if (equivalentA && equivalentB && equivalentA == a)
+        return equivalentB;
+    return nullptr;
+}
+
+std::map<const JSonElement *, const JSonElement *> LevenshteinMatriceWithScore::getEquivalences() const
+{
+    std::map<const JSonElement*, const JSonElement *> res;
+    if (equivalentA && equivalentB)
+        res[equivalentA] = equivalentB;
+    return res;
 }
 
 size_t LevenshteinMatriceWithScore::result() const