Hello community,

here is the log from the commit of package picmi for openSUSE:Factory checked 
in at 2013-12-02 12:35:43
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/picmi (Old)
 and      /work/SRC/openSUSE:Factory/.picmi.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "picmi"

Changes:
--------
--- /work/SRC/openSUSE:Factory/picmi/picmi.changes      2013-10-03 
16:06:43.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.picmi.new/picmi.changes 2013-12-02 
12:35:45.000000000 +0100
@@ -1,0 +2,21 @@
+Sat Nov 16 18:32:02 UTC 2013 - tittiatc...@gmail.com
+
+- Update to 4.11.90
+   * KDE 4.12 Beta 2 release
+   * See http://www.kde.org/announcements/announce-4.12-beta2.php
+
+-------------------------------------------------------------------
+Sun Nov 10 08:03:44 UTC 2013 - tittiatc...@gmail.com
+
+- Update to 4.11.80
+   * KDE 4.12 Beta 1 release
+   * See http://www.kde.org/announcements/announce-4.12-beta1.php
+
+-------------------------------------------------------------------
+Sat Nov  2 15:50:22 UTC 2013 - tittiatc...@gmail.com
+
+- Update to 4.11.3
+   * KDE 4.11.3 bugfix release
+   * See http://www.kde.org/announcements/announce-4.11.3.php
+
+-------------------------------------------------------------------

Old:
----
  picmi-4.11.2.tar.xz

New:
----
  picmi-4.11.90.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ picmi.spec ++++++
--- /var/tmp/diff_new_pack.ttkMTt/_old  2013-12-02 12:35:46.000000000 +0100
+++ /var/tmp/diff_new_pack.ttkMTt/_new  2013-12-02 12:35:46.000000000 +0100
@@ -23,7 +23,7 @@
 License:        GPL-2.0+
 Group:          Amusements/Games/Board/Logic
 Url:            http://www.kde.org
-Version:        4.11.2
+Version:        4.11.90
 Release:        0
 Source0:        picmi-%{version}.tar.xz
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build

++++++ picmi-4.11.2.tar.xz -> picmi-4.11.90.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picmi-4.11.2/CMakeLists.txt 
new/picmi-4.11.90/CMakeLists.txt
--- old/picmi-4.11.2/CMakeLists.txt     2013-06-28 20:01:04.000000000 +0200
+++ new/picmi-4.11.90/CMakeLists.txt    2013-10-28 05:05:57.000000000 +0100
@@ -12,11 +12,14 @@
 find_package(KDE4 REQUIRED)
 find_package(KDEGames 4.9.0 REQUIRED)
 
+include(KDE4Defaults)
+
 add_subdirectory(themes)
 add_subdirectory(icons)
 add_subdirectory(doc)
 add_subdirectory(levels)
 add_subdirectory(src)
+add_subdirectory(test)
 
 install(FILES ${CMAKE_SOURCE_DIR}/picmi.desktop DESTINATION 
${XDG_APPS_INSTALL_DIR})
 install(FILES ${CMAKE_SOURCE_DIR}/picmiui.rc DESTINATION 
${DATA_INSTALL_DIR}/picmi)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picmi-4.11.2/GNUmakefile 
new/picmi-4.11.90/GNUmakefile
--- old/picmi-4.11.2/GNUmakefile        2013-06-28 20:01:04.000000000 +0200
+++ new/picmi-4.11.90/GNUmakefile       2013-10-28 05:05:57.000000000 +0100
@@ -2,6 +2,9 @@
        mkdir -p build
        cd build; cmake -DCMAKE_BUILD_TYPE="Debug" 
-DCMAKE_INSTALL_PREFIX="/usr" -DQT_QMAKE_EXECUTABLE=qmake-qt4 ..; make -j3
 
+check: bake
+       cd build; ctest --output-on-failure
+
 clean:
        rm -r build
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picmi-4.11.2/INSTALL new/picmi-4.11.90/INSTALL
--- old/picmi-4.11.2/INSTALL    2013-06-28 20:01:04.000000000 +0200
+++ new/picmi-4.11.90/INSTALL   2013-10-28 05:05:57.000000000 +0100
@@ -26,16 +26,6 @@
 
 
 
-Installation from AUR (Archlinux)
--------------------
-
-Install using your favorite AUR helper or manually with wget && makepkg && 
pacman -U.
-
-Package Name: picmi-git
-URL: https://aur.archlinux.org/packages.php?ID=56720
-
-
-
 Manual Installation
 -------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picmi-4.11.2/TODO new/picmi-4.11.90/TODO
--- old/picmi-4.11.2/TODO       2013-06-28 20:01:04.000000000 +0200
+++ new/picmi-4.11.90/TODO      2013-10-28 05:05:57.000000000 +0100
@@ -1,8 +1,5 @@
 * frontend to save states - menu items, maybe an extra pane
 * improve level selection window (sorting, filtering)
-* refactoring
-    improve streak calculation
-    ...
 * display statistics: highscores should be displayed at the end of each game,
   listing the current position (#123 out of 323 played), # of game completed,
   # of games incomplete, average time, current time. the score window should
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picmi-4.11.2/picmi.desktop 
new/picmi-4.11.90/picmi.desktop
--- old/picmi-4.11.2/picmi.desktop      2013-08-28 19:13:31.000000000 +0200
+++ new/picmi-4.11.90/picmi.desktop     2013-10-28 05:05:57.000000000 +0100
@@ -24,6 +24,7 @@
 Name[pl]=picmi
 Name[pt]=picmi
 Name[pt_BR]=picmi
+Name[ro]=picmi
 Name[ru]=picmi
 Name[sk]=picmi
 Name[sl]=picmi
@@ -62,6 +63,7 @@
 GenericName[pl]=Gra logiczna
 GenericName[pt]=Jogo de Lógica
 GenericName[pt_BR]=Jogo de lógica
+GenericName[ro]=Joc de logică
 GenericName[ru]=Логическая игра
 GenericName[sk]=Logická hra
 GenericName[sl]=Logična igra
@@ -71,6 +73,7 @@
 GenericName[sr@latin]=Logička igra
 GenericName[sv]=Logikspel
 GenericName[tr]=Mantık Oyunu
+GenericName[ug]=لوگىكىلىق ئويۇن
 GenericName[uk]=Гра на логіку
 GenericName[x-test]=xxLogic Gamexx
 GenericName[zh_CN]=逻辑游戏
@@ -98,6 +101,7 @@
 Comment[pl]=Liczbowa gra logiczna
 Comment[pt]=Um jogo lógico com números
 Comment[pt_BR]=Jogo de lógica com números
+Comment[ro]=Joc de logică cu numere
 Comment[ru]=Логическая игра с числами
 Comment[sk]=Číselná logická hra
 Comment[sl]=Logična igra s številkami
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picmi-4.11.2/src/gui/graphicsitems/streakitem.cpp 
new/picmi-4.11.90/src/gui/graphicsitems/streakitem.cpp
--- old/picmi-4.11.2/src/gui/graphicsitems/streakitem.cpp       2013-06-28 
20:01:04.000000000 +0200
+++ new/picmi-4.11.90/src/gui/graphicsitems/streakitem.cpp      2013-10-28 
05:05:57.000000000 +0100
@@ -59,12 +59,12 @@
 }
 
 void RowStreakItem::refresh() {
-    QVector<QSharedPointer<Streaks::StreakElement> > streak = 
m_game->getRowStreak(m_y);
+    QVector<Streaks::Streak> streak = m_game->getRowStreak(m_y);
     QString text;
 
     for (int i = 0; i < (int)streak.size(); i++) {
-        QString color = (streak[i]->solved ? m_color_solved : 
m_color_unsolved);
-        text.append(QString("<font 
color=\"%1\">%2</font>").arg(color).arg(streak[i]->value));
+        QString color = (streak[i].solved ? m_color_solved : m_color_unsolved);
+        text.append(QString("<font 
color=\"%1\">%2</font>").arg(color).arg(streak[i].value));
         if (i != (int)streak.size() - 1) {
             text.append(" ");
         }
@@ -98,12 +98,12 @@
 }
 
 void ColStreakItem::refresh() {
-    QVector<QSharedPointer<Streaks::StreakElement> > streak = 
m_game->getColStreak(m_x);
+    QVector<Streaks::Streak> streak = m_game->getColStreak(m_x);
     QString text;
 
     for (int i = 0; i < (int)streak.size(); i++) {
-        QString color = (streak[i]->solved ? m_color_solved : 
m_color_unsolved);
-        text.append(QString("<font 
color=\"%1\">%2</font>").arg(color).arg(streak[i]->value));
+        QString color = (streak[i].solved ? m_color_solved : m_color_unsolved);
+        text.append(QString("<font 
color=\"%1\">%2</font>").arg(color).arg(streak[i].value));
         if (i != (int)streak.size() - 1) {
             text.append("<br/>");
         }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picmi-4.11.2/src/logic/picmi.cpp 
new/picmi-4.11.90/src/logic/picmi.cpp
--- old/picmi-4.11.2/src/logic/picmi.cpp        2013-08-28 19:13:31.000000000 
+0200
+++ new/picmi-4.11.90/src/logic/picmi.cpp       2013-10-28 05:05:57.000000000 
+0100
@@ -140,18 +140,18 @@
        this by ending the game once all streaks are marked solved. */
 
     for (int x = 0; x < width(); x++) {
-        QVector<QSharedPointer<Streaks::StreakElement> > streak = 
getColStreak(x);
+        QVector<Streaks::Streak> streak = getColStreak(x);
         for (int i = 0; i < (int)streak.size(); i++) {
-            if (!streak[i]->solved) {
+            if (!streak[i].solved) {
                 return false;
             }
         }
     }
 
     for (int y = 0; y < height(); y++) {
-        QVector<QSharedPointer<Streaks::StreakElement> > streak = 
getRowStreak(y);
+        QVector<Streaks::Streak> streak = getRowStreak(y);
         for (int i = 0; i < (int)streak.size(); i++) {
-            if (!streak[i]->solved) {
+            if (!streak[i].solved) {
                 return false;
             }
         }
@@ -249,9 +249,10 @@
     }
 }
 
-QVector<QSharedPointer<Streaks::StreakElement> > Picmi::getRowStreak(int y) 
const {
+QVector<Streaks::Streak> Picmi::getRowStreak(int y) const {
     return m_streaks->getRowStreak(y);
 }
-QVector<QSharedPointer<Streaks::StreakElement> > Picmi::getColStreak(int x) 
const {
+
+QVector<Streaks::Streak> Picmi::getColStreak(int x) const {
     return m_streaks->getColStreak(x);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picmi-4.11.2/src/logic/picmi.h 
new/picmi-4.11.90/src/logic/picmi.h
--- old/picmi-4.11.2/src/logic/picmi.h  2013-08-28 19:13:31.000000000 +0200
+++ new/picmi-4.11.90/src/logic/picmi.h 2013-10-28 05:05:57.000000000 +0100
@@ -87,8 +87,8 @@
     /* returns the request row/col streak. these contain the least information 
required by
       the frontend, which is (for each position within a streak): "which 
number is this",
       and "is this position solved" */
-    QVector<QSharedPointer<Streaks::StreakElement> > getRowStreak(int y) const;
-    QVector<QSharedPointer<Streaks::StreakElement> > getColStreak(int x) const;
+    QVector<Streaks::Streak> getRowStreak(int y) const;
+    QVector<Streaks::Streak> getColStreak(int x) const;
 
 signals:
     /** Emitted when the game has been completed in any way. Also triggered if 
"Solve" was used. */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picmi-4.11.2/src/logic/streaks.cpp 
new/picmi-4.11.90/src/logic/streaks.cpp
--- old/picmi-4.11.2/src/logic/streaks.cpp      2013-06-28 20:01:04.000000000 
+0200
+++ new/picmi-4.11.90/src/logic/streaks.cpp     2013-10-28 05:05:57.000000000 
+0100
@@ -19,38 +19,7 @@
 
 #include <algorithm>
 
-/* 0 <= x < m_width; 0 <= y < m_height; returns a row/col as a sequence of 
states */
-static QVector<Board::State> colToLine(const QSharedPointer<Board> &board, int 
x);
-static QVector<Board::State> rowToLine(const QSharedPointer<Board> &board, int 
y);
-
-/* takes a sequence of states and returns streaks */
-static QVector<int> lineToStreaks(
-        const QVector<Board::State> &line, Board::State filler);
-
-static QVector<QSharedPointer<Streaks::StreakElement> > newStreak(const 
QVector<int> &map);
-static QVector<QSharedPointer<Streaks::StreakElement> > processStreak(
-        const QVector<int> &map, QSharedPointer<LineInfo> state);
-
-
-LineInfo::LineInfo(const QVector<Board::State> &l) : box_count(0), 
cross_count(0)
-{
-    line = l;
-    streaks_regular = lineToStreaks(l, Board::Cross);
-
-    QVector<Board::State> line_reversed(l);
-    std::reverse(line_reversed.begin(), line_reversed.end());
-    streaks_reversed = lineToStreaks(line_reversed, Board::Cross);
-
-    for (int i = 0; i < (int)l.size(); i++) {
-        if (l[i] == Board::Box) {
-            box_count++;
-        } else if (l[i] == Board::Cross) {
-            cross_count++;
-        }
-    }
-}
-
-
+/** 0 <= x < m_width; 0 <= y < m_height; returns a row as a sequence of states 
*/
 static QVector<Board::State> colToLine(const QSharedPointer<Board> &board,
                                        int x)
 {
@@ -61,9 +30,9 @@
     return line;
 }
 
-
+/** 0 <= x < m_width; 0 <= y < m_height; returns a row as a sequence of states 
*/
 static QVector<Board::State> rowToLine(const QSharedPointer<Board> &board,
-                                int y)
+                                       int y)
 {
     QVector<Board::State> line;
     for (int x = 0; x < board->width(); x++) {
@@ -72,108 +41,131 @@
     return line;
 }
 
-static QVector<int> lineToStreaks(const QVector<Board::State> &line,
-                                  Board::State filler)
-{
-    int len = 0;
-    QVector<int> streaks;
+/**
+ * Streaks are generated using a simple state machine. Either we're in a filler
+ * section (Nothing for map streaks, Cross for state streaks), or we're in a 
Box
+ * streak. A final possibility is that we're done processing.
+ */
+
+enum {
+    S_FILLER,
+    S_STREAK,
+    S_END
+};
+
+QVector<Streaks::StreakPrivate>
+Streaks::lineToStreaks(const QVector<Board::State> &line,
+                       Board::State filler)
+{
+    StreakPrivate s;
+    QVector<StreakPrivate> streaks;
+    int state = S_FILLER;
 
     for (int i = 0; i < line.size(); i++) {
-        if (line[i] == Board::Box) {
-            len++;
-        } else if (line[i] == filler) {
-            if (len > 0) {
-                streaks.push_back(len);
-                len = 0;
+        const Board::State t = line[i];
+
+        switch (state) {
+        case S_FILLER:
+            if (t == Board::Box) {
+                s.begin = i;
+                s.value = 0;
+                state = S_STREAK;
+            } else if (t == filler) {
+                /* Nothing. */
+            } else {
+                state = S_END;
             }
-        } else {
             break;
+        case S_STREAK:
+            if (t == Board::Box) {
+                /* Nothing. */
+            } else {
+                s.end = i;
+                s.value = s.end - s.begin;
+                streaks.append(s);
+                state = (t == filler) ? S_FILLER : S_END;
+            }
+            break;
+        case S_END:
+        default:
+            return streaks;
         }
     }
 
-    if (len > 0) {
-        streaks.push_back(len);
-        len = 0;
+    if (state == S_STREAK) {
+        s.end = line.size();
+        s.value = s.end - s.begin;
+        streaks.append(s);
     }
 
     return streaks;
 }
 
-static QVector<QSharedPointer<Streaks::StreakElement> > processStreak(
-        const QVector<int> &map, QSharedPointer<LineInfo> state)
-{
-    const bool line_complete = (state->box_count + state->cross_count == 
(int)state->line.size());
-    QVector<QSharedPointer<Streaks::StreakElement> > streak = newStreak(map);
+QVector<Streaks::Streak>
+Streaks::processStreak(const QVector<StreakPrivate> &map,
+                       const QVector<Board::State> &l)
+{        
+    QVector<Streaks::Streak> streak;
+    QVector<StreakPrivate *> assocs(map.size(), NULL);
 
-    /* line is not completely filled, so state and state_reversed are 
disjoint. */
-    if (!line_complete && (state->streaks_regular.size() + 
state->streaks_reversed.size() > map.size())) {
-        return streak;
-    }
+    /* Initial values for returned streaks. */
 
-    bool solved = (map.size() == state->streaks_regular.size());
-    int upper_bound = qMin(map.size(), state->streaks_regular.size());
-    for (int i = 0; i < upper_bound; i++) {
-        if (map[i] != state->streaks_regular[i]) {
-            solved = false;
-            break;
-        }
-        streak[i]->solved = true;
+    for (int i = 0; i < map.size(); i++) {
+        streak.push_back(map[i]);
     }
 
-    /* if the line has been filled completely with either crosses or boxes, we 
already have enough information
-       here */
+    /* Create the state streaks. */
+
+    QVector<StreakPrivate> streaks_regular = lineToStreaks(l, Board::Cross);
+
+    QVector<Board::State> line_reversed(l);
+    std::reverse(line_reversed.begin(), line_reversed.end());
+    QVector<StreakPrivate> streaks_reversed = lineToStreaks(line_reversed, 
Board::Cross);
+
+    /* Fix begin and end indices of reversed streaks. */
 
-    if (line_complete) {
-        return (solved ? streak : newStreak(map));
+    for (int i = 0; i < streaks_reversed.size(); i++) {
+        streaks_reversed[i].begin = l.size() - streaks_reversed[i].begin;
+        streaks_reversed[i].end   = l.size() - streaks_reversed[i].end;
+        qSwap(streaks_reversed[i].begin, streaks_reversed[i].end);
     }
 
-    upper_bound = qMin(map.size(), state->streaks_reversed.size());
-    for (int i = 0; i < upper_bound; i++) {
-        /* streak is "reversed" -> process state streak from front, map streak 
from back */
-        int index = map.size() - 1 - i;
-        if (map[index] != state->streaks_reversed[i]) {
-            break;
-        }
-        streak[index]->solved = true;
+    /* Preliminary checks. */
+
+    if (streaks_regular.size() > map.size() || streaks_reversed.size() > 
map.size()) {
+        return streak;
     }
 
-    bool fully_solved = true;
-    int actual_box_count = 0;
-    for (int i = 0; i < (int)streak.size(); i++) {
-        if (!streak[i]->solved) {
-            fully_solved = false;
-            break;
+    /* The concept of this check is fairly simple, and consists of two passes:
+     * 1. Compare and match the regular state streaks to map streaks.
+     * 2. Compare and match the reverse state streaks to map streaks.
+     * A streak is solved, iff it is matched with exactly one streak (reverse
+     * or regular), or it is matched with two and their begin and end indices 
match.
+     */
+
+    for (int i = 0; i < streaks_regular.size(); i++) {
+        streak[i].solved = (streak[i].value == streaks_regular[i].value);
+        assocs[i] = &streaks_regular[i];
+    }
+
+    for (int i = 0; i < streaks_reversed.size(); i++) {
+        const int ix = map.size() - i - 1;
+
+        streak[ix].solved = (streak[ix].value == streaks_reversed[i].value);
+
+        if (assocs[ix] != NULL) {
+            const bool range_matches = (assocs[ix]->begin == 
streaks_reversed[i].begin &&
+                                        assocs[ix]->end   == 
streaks_reversed[i].end);
+            streak[ix].solved &= range_matches;
         }
-        actual_box_count += streak[i]->value;
-    }
-    if (fully_solved && actual_box_count != state->box_count) {
-        return newStreak(map);
     }
 
     return streak;
 }
 
-static QVector<QSharedPointer<Streaks::StreakElement> > newStreak(const 
QVector<int> &map)
-{
-    QVector<QSharedPointer<Streaks::StreakElement> > streak;
-    for (int i = 0; i < (int)map.size(); i++) {
-        QSharedPointer<Streaks::StreakElement> element(new 
Streaks::StreakElement);
-        element->value = map[i];
-        element->solved = false;
-        streak.push_back(element);
-    }
-    return streak;
-}
-
-
 Streaks::Streaks(QSharedPointer<BoardMap> map, QSharedPointer<BoardState> 
state)
     : m_map(map), m_state(state)
 {
-    calcMapStreaks();
-    update();
-}
-
-void Streaks::calcMapStreaks() {
     for (int x = 0; x < m_map->width(); x++) {
         QVector<Board::State> line = colToLine(m_map, x);
         m_map_col_streaks.push_back(lineToStreaks(line, Board::Nothing));
@@ -183,31 +175,31 @@
         QVector<Board::State> line = rowToLine(m_map, y);
         m_map_row_streaks.push_back(lineToStreaks(line, Board::Nothing));
     }
+
+    update();
 }
 
 void Streaks::update(int x, int y) {
-    m_state_col_streaks[x] = QSharedPointer<LineInfo>(new 
LineInfo(colToLine(m_state, x)));
-    m_state_row_streaks[y] = QSharedPointer<LineInfo>(new 
LineInfo(rowToLine(m_state, y)));
+    m_state_col_streaks[x] = processStreak(m_map_col_streaks[x], 
colToLine(m_state, x));
+    m_state_row_streaks[y] = processStreak(m_map_row_streaks[y], 
rowToLine(m_state, y));
 }
 
 void Streaks::update() {
     m_state_col_streaks.clear();
     for (int x = 0; x < m_state->width(); x++) {
-        QSharedPointer<LineInfo> line(new LineInfo(colToLine(m_state, x)));
-        m_state_col_streaks.push_back(line);
+        m_state_col_streaks.push_back(processStreak(m_map_col_streaks[x], 
colToLine(m_state, x)));
     }
 
     m_state_row_streaks.clear();
     for (int y = 0; y < m_state->height(); y++) {
-        QSharedPointer<LineInfo> line(new LineInfo(rowToLine(m_state, y)));
-        m_state_row_streaks.push_back(line);
+        m_state_row_streaks.push_back(processStreak(m_map_row_streaks[y], 
rowToLine(m_state, y)));
     }
 }
 
-QVector<QSharedPointer<Streaks::StreakElement> > Streaks::getRowStreak(int y) 
const {
-    return processStreak(m_map_row_streaks[y], m_state_row_streaks[y]);
+QVector<Streaks::Streak> Streaks::getRowStreak(int y) const {
+    return m_state_row_streaks[y];
 }
 
-QVector<QSharedPointer<Streaks::StreakElement> > Streaks::getColStreak(int x) 
const {
-    return processStreak(m_map_col_streaks[x], m_state_col_streaks[x]);
+QVector<Streaks::Streak> Streaks::getColStreak(int x) const {
+    return m_state_col_streaks[x];
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picmi-4.11.2/src/logic/streaks.h 
new/picmi-4.11.90/src/logic/streaks.h
--- old/picmi-4.11.2/src/logic/streaks.h        2013-06-28 20:01:04.000000000 
+0200
+++ new/picmi-4.11.90/src/logic/streaks.h       2013-10-28 05:05:57.000000000 
+0100
@@ -24,22 +24,11 @@
 #include "boardmap.h"
 #include "boardstate.h"
 
-/* Moved from streaks.cpp to work around QSharedPointer issues with forward 
declarations.
- * TODO: move this back once when Qt 5 is used. */
-struct LineInfo {
-    LineInfo(const QVector<Board::State> &l);
-
-    int box_count;
-    int cross_count;
-    QVector<int> streaks_regular;
-    QVector<int> streaks_reversed;
-    QVector<Board::State> line;
-};
-
 class Streaks
 {
 public:
-    struct StreakElement {
+    struct Streak {
+        Streak() : solved(false) { }
         int value;
         bool solved;
     };
@@ -55,22 +44,41 @@
     /* Returns the request row/col streak. These contain the least information 
required by
        the frontend, which is (for each position within a streak): "which 
number is this",
        and "is this position solved" */
-    QVector<QSharedPointer<Streaks::StreakElement> > getRowStreak(int y) const;
-    QVector<QSharedPointer<Streaks::StreakElement> > getColStreak(int x) const;
-
-private:
+    QVector<Streaks::Streak> getRowStreak(int y) const;
+    QVector<Streaks::Streak> getColStreak(int x) const;
 
-    void calcMapStreaks();
+private: /* Types. */
+    struct StreakPrivate : public Streak {
+        int begin;  /**< The first index of this streak. */
+        int end;    /**< The first index after this streak. */
+    };
 
+private: /* Functions. */
+    /* Takes a sequence of states and returns streaks. */
+    static QVector<StreakPrivate> lineToStreaks(const QVector<Board::State> 
&line,
+                                                Board::State filler);
+
+    /** Given a map streak sequence as well as the current state of the 
associated line,
+     *  processStreak() returns the state streaks. */
+    static QVector<Streak> processStreak(const QVector<StreakPrivate> &map,
+                                         const QVector<Board::State> &l);
 
+private: /* Variables. */
     QSharedPointer<BoardMap> m_map;
     QSharedPointer<BoardState> m_state;
 
-    QVector<QVector<int> > m_map_row_streaks;
-    QVector<QVector<int> > m_map_col_streaks;
-
-    QVector<QSharedPointer<LineInfo> > m_state_row_streaks;
-    QVector<QSharedPointer<LineInfo> > m_state_col_streaks;
+    /** Map streaks are calculated once upon construction and then stay 
immutable
+     *  for the remaining lifetime of a Streaks object. They store information 
about
+     *  the actual map streaks, including the streak beginning index, end 
index, and
+     *  length. */
+    QVector<QVector<StreakPrivate> > m_map_row_streaks;
+    QVector<QVector<StreakPrivate> > m_map_col_streaks;
+
+    /** State streaks are recomputed whenever the state of an associated cell 
changes.
+     *  Unlike the map streaks, row streaks only store the publicly available 
information:
+     *  the length of a streak, and whether it's solved or not. */
+    QVector<QVector<Streak> > m_state_row_streaks;
+    QVector<QVector<Streak> > m_state_col_streaks;
 };
 
 #endif // STREAKS_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picmi-4.11.2/test/CMakeLists.txt 
new/picmi-4.11.90/test/CMakeLists.txt
--- old/picmi-4.11.2/test/CMakeLists.txt        1970-01-01 01:00:00.000000000 
+0100
+++ new/picmi-4.11.90/test/CMakeLists.txt       2013-10-28 05:05:57.000000000 
+0100
@@ -0,0 +1 @@
+add_subdirectory(logic)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picmi-4.11.2/test/logic/CMakeLists.txt 
new/picmi-4.11.90/test/logic/CMakeLists.txt
--- old/picmi-4.11.2/test/logic/CMakeLists.txt  1970-01-01 01:00:00.000000000 
+0100
+++ new/picmi-4.11.90/test/logic/CMakeLists.txt 2013-10-28 05:05:57.000000000 
+0100
@@ -0,0 +1,21 @@
+set(streaks_test_SRCS
+    streaks_test.cpp
+)
+
+include_directories(
+    ${CMAKE_SOURCE_DIR}/src/logic
+    ${CMAKE_SOURCE_DIR}
+)
+
+kde4_add_unit_test(streaks_test
+    TESTNAME streaks-test
+    ${streaks_test_SRCS}
+)
+
+target_link_libraries(streaks_test
+    picmi_logic
+    ${QT_QTTEST_LIBRARY}
+    ${QT_LIBRARIES}
+)
+
+# vim:set ts=4 sw=4 et:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picmi-4.11.2/test/logic/streaks_test.cpp 
new/picmi-4.11.90/test/logic/streaks_test.cpp
--- old/picmi-4.11.2/test/logic/streaks_test.cpp        1970-01-01 
01:00:00.000000000 +0100
+++ new/picmi-4.11.90/test/logic/streaks_test.cpp       2013-10-28 
05:05:57.000000000 +0100
@@ -0,0 +1,225 @@
+#include "streaks_test.h"
+
+#include <QTest>
+
+#include "streaks.h"
+
+QTEST_MAIN(StreaksTest)
+
+#define STREAK_TEST(map, state, expected) do { \
+    QSharedPointer<Streaks> s = generateStreaks(map, state); \
+    if (!s) { \
+        QFAIL("Streak generation failed."); \
+    } \
+    QVector<Streaks::Streak> row = s->getRowStreak(0); \
+    QVERIFY(streakEquals(row, expected)); \
+} while (false);
+
+/**
+ * Generates a Streaks instance from the given string representations
+ * of map and state. A map string consists of '.' and 'b' chars, representing
+ * respectively Nothing and Box cells. A state string consists of '.', 'b' and
+ * 'x' chars (with 'x' representing cross cells). If the board has more than
+ * one row, each line is terminated by '\n'.
+ */
+static QSharedPointer<Streaks>
+generateStreaks(const QString &map, const QString &state)
+{
+    if (map.size() != state.size()) {
+        return QSharedPointer<Streaks>();
+    }
+
+    /* Generate the map. */
+
+    QList<Board::State> ss;
+    for (int i = 0; i < map.size(); i++) {
+        switch (map[i].toAscii()) {
+        case '.': /* Nothing. */
+            ss.append(Board::Nothing);
+            break;
+        case 'b': /* Box. */
+            ss.append(Board::Box);
+            break;
+        default:
+            return QSharedPointer<Streaks>();
+        }
+    }
+
+    QSharedPointer<BoardMap> mptr(new BoardMap(map.size(), 1, ss));
+
+    /* Generate the state. */
+
+    QSharedPointer<BoardState> sptr(new BoardState(state.size(), 1));
+
+    for (int i = 0; i < state.size(); i++) {
+        switch (state[i].toAscii()) {
+        case '.': /* Nothing. */
+            break;
+        case 'b': /* Box. */
+            sptr->set(i, 0, Board::Box);
+            break;
+        case 'x': /* Cross. */
+            sptr->set(i, 0, Board::Cross);
+            break;
+        default:
+            return QSharedPointer<Streaks>();
+        }
+    }
+
+    return QSharedPointer<Streaks>(new Streaks(mptr, sptr));
+}
+
+/**
+ * Compares the actual streak result against a string representing the
+ * expected result. The string consists of 'x' and '.' characters representing,
+ * respectively, solved and unsolved streaks.
+ */
+static bool
+streakEquals(const QVector<Streaks::Streak> &actual,
+             const QString &expected)
+{
+    if (actual.size() != expected.size()) {
+        QWARN("Actual size not equal to expected size.");
+        return false;
+    }
+
+    QString actualString;
+
+    for (int i = 0; i < expected.size(); i++) {
+        if (actual[i].solved) {
+            actualString.append('x');
+        } else {
+            actualString.append('.');
+        }
+    }
+
+    if (actualString == expected) {
+        return true;
+    }
+
+    QString msg = "Result mismatch. Actual: " + actualString + ", Expected: " 
+ expected;
+    QWARN(msg.toAscii());
+
+    return false;
+}
+
+void StreaksTest::testSanity()
+{
+    QSharedPointer<Streaks> s = generateStreaks("....b", "xxxxb");
+
+    QCOMPARE(1, 1);
+}
+
+void StreaksTest::test00()
+{
+    /* Lifted from https://bugs.kde.org/show_bug.cgi?id=321842 */
+    STREAK_TEST("bb.b.bbbb.bbb.b",
+                "bbxbxbb.bxbbbxb",
+                "xx.xx");
+}
+
+void StreaksTest::test01()
+{
+    /* Lifted from https://bugs.kde.org/show_bug.cgi?id=321842 */
+    STREAK_TEST("bb.b.bbbb.bbb.b",
+                "bbxbxbb.bxb.bxb",
+                "xx..x");
+}
+
+void StreaksTest::test02()
+{
+    /* Lifted from https://bugs.kde.org/show_bug.cgi?id=321842 */
+    STREAK_TEST("bb.b.bbbb.bbb.b",
+                "bbxbxbbbbxbbbxb",
+                "xxxxx");
+}
+
+void StreaksTest::test03()
+{
+    STREAK_TEST("bb.b.bbbb.bbb.b",
+                "bbxbxbbbbxbb...",
+                "xxx..");
+}
+
+void StreaksTest::test04()
+{
+    STREAK_TEST("bb.b.bbbb.bbb.b",
+                "bbxbxbbbbxbbb..",
+                "xxxx.");
+}
+
+void StreaksTest::test05()
+{
+    STREAK_TEST("b.b.......",
+                "bxb....bxb",
+                "..");
+}
+
+void StreaksTest::test06()
+{
+    STREAK_TEST("b.b.......",
+                "b........b",
+                "xx");
+}
+
+void StreaksTest::test07()
+{
+    STREAK_TEST("b.b.......",
+                "bxb....bxb",
+                "..");
+}
+
+void StreaksTest::test08()
+{
+    STREAK_TEST("b.b.......",
+                "bxb.......",
+                "xx");
+}
+
+void StreaksTest::test09()
+{
+    STREAK_TEST("b.bb.bbb.",
+                "bxbb..bbb",
+                "xxx");
+}
+
+void StreaksTest::test10()
+{
+    STREAK_TEST("b.bb.bbb.",
+                "bxb...bbb",
+                "x.x");
+}
+
+void StreaksTest::test11()
+{
+    STREAK_TEST("b.bb.bbb.",
+                "bxbbxxbbb",
+                "xxx");
+}
+
+void StreaksTest::test12()
+{
+    STREAK_TEST("bb.b.....",
+                "bb...xbxb",
+                ".x");
+}
+
+void StreaksTest::test13()
+{
+    STREAK_TEST("b.b.b.b.bb",
+                "bbbxbxb...",
+                ".xx..");
+}
+
+void StreaksTest::bench00()
+{
+    QSharedPointer<Streaks> s = generateStreaks("b.b.b.b.bbb.b.b.b.bb",
+                                                "bbbxbxb...bbbxbxb...");
+    if (!s) {
+        QFAIL("Streak generation failed.");
+    }
+    QBENCHMARK {
+        s->update(0, 0);
+        s->getRowStreak(0);
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picmi-4.11.2/test/logic/streaks_test.h 
new/picmi-4.11.90/test/logic/streaks_test.h
--- old/picmi-4.11.2/test/logic/streaks_test.h  1970-01-01 01:00:00.000000000 
+0100
+++ new/picmi-4.11.90/test/logic/streaks_test.h 2013-10-28 05:05:57.000000000 
+0100
@@ -0,0 +1,29 @@
+#ifndef __STREAKS_TEST_H
+#define __STREAKS_TEST_H
+
+#include <QObject>
+
+class StreaksTest : public QObject
+{
+    Q_OBJECT
+
+private slots:
+    void testSanity();
+    void test00();
+    void test01();
+    void test02();
+    void test03();
+    void test04();
+    void test05();
+    void test06();
+    void test07();
+    void test08();
+    void test09();
+    void test10();
+    void test11();
+    void test12();
+    void test13();
+    void bench00();
+};
+
+#endif /* __STREAKS_TEST_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/picmi-4.11.2/themes/picmi.desktop 
new/picmi-4.11.90/themes/picmi.desktop
--- old/picmi-4.11.2/themes/picmi.desktop       2013-08-28 19:13:31.000000000 
+0200
+++ new/picmi-4.11.90/themes/picmi.desktop      2013-10-28 05:05:57.000000000 
+0100
@@ -25,6 +25,7 @@
 Name[pl]=Picmi
 Name[pt]=Picmi
 Name[pt_BR]=Picmi
+Name[ro]=Picmi
 Name[ru]=Picmi
 Name[sk]=Picmi
 Name[sl]=Picmi

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to