[Digikam-devel] branches/extragear/kde3/graphics/digikam/digikam

Gilles Caulier caulier.gilles at gmail.com
Fri Jan 11 13:38:09 CET 2008


SVN commit 759898 by cgilles:

digiKam from KDE3 branch : TimeLine: Fuzzy Selection is now possible!!!

Before this commit, selection been depand of Time Units used with time line. Each unit have a propers selection.
This first approach been not fine...

This commit only make the selection on the less Time Units : Day. All others Units are updated accordinly. 
There is only one Selection possible, not one for each Time Units.

A fuzzy range date become when for a week for ex. you have selected only 2 days. The week selection is uncomplete (fuzzy).
This is right too between week/Month and Month/Year Time units.

On the bottom of the widget, the complete selection is annoted by a blue color in background. 
A fuzzy selection is annoted by a light-blue color using a drawing pattern.

In fact, this is the same concept used in KPhotoalbum for ex., excepted a major difference : digiKam can select dyscontiguous range of dates (:=)))

Marcel, 

i have working hard with algorithms used in this widget. I would to have your viewpoint to be sure than all is fine with TimeLine selection.

Also, the KUrl passed to digiKam search KIO-Slave can be very long. I'm not sure if there is a limit somewhere in KUrl or digiKam Search KIO-Slave. 
In theory no (:=)))... If there is one, the DB query will fail, that all (KUrl truncated).

CCMAIL: digikam-devel at kde.org
CCMAIL: marcel.wiesweg at gmx.de



 M  +3 -1      timelineview.cpp  
 M  +118 -128  timelinewidget.cpp  
 M  +23 -21    timelinewidget.h  


--- branches/extragear/kde3/graphics/digikam/digikam/timelineview.cpp #759897:759898
@@ -265,6 +265,8 @@
         return;
     }
 
+    // We will make now the Url for digiKam Search KIO-Slave
+
     KURL url;
     url.setProtocol("digikamsearch");
 
@@ -312,7 +314,7 @@
 
 void TimeLineView::slotResetSelection()
 {
-    d->timeLineWidget->resetSelection();
+    d->timeLineWidget->slotResetSelection();
     AlbumManager::instance()->setCurrentAlbum(0);
 }
 
--- branches/extragear/kde3/graphics/digikam/digikam/timelinewidget.cpp #759897:759898
@@ -297,63 +297,30 @@
     return statForDateTime(start, selected);
 }
 
-void TimeLineWidget::resetSelection()
+void TimeLineWidget::slotResetSelection()
 {
-    resetSelection(d->dateMode);
+    resetSelection();
     updatePixmap();
     update();
 }
 
-void TimeLineWidget::resetAllSelection()
+void TimeLineWidget::resetSelection()
 {
-    for (int i=(int)Day ; i<=(int)Year ; i++)
-        resetSelection((TimeLineWidget::DateMode)i);
+    QMap<TimeLineWidgetPriv::YearRefPair, TimeLineWidgetPriv::StatPair>::iterator it;
 
-    updatePixmap();
-    update();
-}
+    for (it = d->dayStatMap.begin() ; it != d->dayStatMap.end(); ++it)
+        it.data().second = Unselected;
 
-void TimeLineWidget::resetSelection(TimeLineWidget::DateMode mode)
-{
-    switch(mode)
-    {
-        case Day:
-        {
-            QMap<TimeLineWidgetPriv::YearRefPair, TimeLineWidgetPriv::StatPair>::iterator it;
+    for (it = d->weekStatMap.begin() ; it != d->weekStatMap.end(); ++it)
+        it.data().second = Unselected;
 
-            for (it = d->dayStatMap.begin() ; it != d->dayStatMap.end(); ++it)
-                it.data().second = Unselected;
+    for (it = d->monthStatMap.begin() ; it != d->monthStatMap.end(); ++it)
+        it.data().second = Unselected;
 
-            break;
-        }
-        case Week:
-        {
-            QMap<TimeLineWidgetPriv::YearRefPair, TimeLineWidgetPriv::StatPair>::iterator it;
+    QMap<int, TimeLineWidgetPriv::StatPair>::iterator it2;
 
-            for (it = d->weekStatMap.begin() ; it != d->weekStatMap.end(); ++it)
-                it.data().second = Unselected;
-
-            break;
-        }
-        case Month:
-        {
-            QMap<TimeLineWidgetPriv::YearRefPair, TimeLineWidgetPriv::StatPair>::iterator it;
-
-            for (it = d->monthStatMap.begin() ; it != d->monthStatMap.end(); ++it)
-                it.data().second = Unselected;
-
-            break;
-        }
-        case Year:
-        {
-            QMap<int, TimeLineWidgetPriv::StatPair>::iterator it;
-
-            for (it = d->yearStatMap.begin() ; it != d->yearStatMap.end(); ++it)
-                it.data().second = Unselected;
-
-            break;
-        }
-    }
+    for (it2 = d->yearStatMap.begin() ; it2 != d->yearStatMap.end(); ++it2)
+        it2.data().second = Unselected;
 }
 
 void TimeLineWidget::setSelectedDateRange(const DateRangeList& list)
@@ -363,89 +330,34 @@
 
 DateRangeList TimeLineWidget::selectedDateRange(int& totalCount)
 {
-    totalCount = 0;
+    // We wil parse all selected done on days stats map.
+
     DateRangeList list;
+    totalCount = 0;
+    QMap<TimeLineWidgetPriv::YearRefPair, TimeLineWidgetPriv::StatPair>::iterator it3;
 
-    switch(d->dateMode)
+    for (it3 = d->dayStatMap.begin() ; it3 != d->dayStatMap.end(); ++it3)
     {
-        case Day:
+        if (it3.data().second == Selected)
         {
-            QMap<TimeLineWidgetPriv::YearRefPair, TimeLineWidgetPriv::StatPair>::iterator it;
-
-            for (it = d->dayStatMap.begin() ; it != d->dayStatMap.end(); ++it)
-            {
-                if (it.data().second == Selected)
-                {
-                    QDate date(it.key().first, 1, 1);
-                    date = date.addDays(it.key().second-1);
-                    QDateTime sdt(date);
-                    QDateTime edt = nextDateTime(sdt); 
-                    list.append(DateRange(sdt, edt));
-                    totalCount += it.data().first;
-                }
-            }
-            break;
+            QDate date(it3.key().first, 1, 1);
+            date = date.addDays(it3.key().second-1);
+            QDateTime sdt(date);
+            QDateTime edt = nextDateTime(sdt); 
+            list.append(DateRange(sdt, edt));
+            totalCount += it3.data().first;
         }
-        case Week:
-        {
-            QMap<TimeLineWidgetPriv::YearRefPair, TimeLineWidgetPriv::StatPair>::iterator it;
-
-            for (it = d->weekStatMap.begin() ; it != d->weekStatMap.end(); ++it)
-            {
-                if (it.data().second == Selected)
-                {
-                    QDateTime sdt = firstDayOfWeek(it.key().first, it.key().second);
-                    QDateTime edt = nextDateTime(sdt); 
-                    list.append(DateRange(sdt, edt));
-                    totalCount += it.data().first;
-                }
-            }
-            break;
-        }
-        case Month:
-        {
-            QMap<TimeLineWidgetPriv::YearRefPair, TimeLineWidgetPriv::StatPair>::iterator it;
-
-            for (it = d->monthStatMap.begin() ; it != d->monthStatMap.end(); ++it)
-            {
-                if (it.data().second == Selected)
-                {
-                    QDate date(it.key().first, it.key().second, 1);
-                    QDateTime sdt(date);
-                    QDateTime edt = nextDateTime(sdt); 
-                    list.append(DateRange(sdt, edt));
-                    totalCount += it.data().first;
-                }
-            }
-            break;
-        }
-        case Year:
-        {
-            QMap<int, TimeLineWidgetPriv::StatPair>::iterator it;
-
-            for (it = d->yearStatMap.begin() ; it != d->yearStatMap.end(); ++it)
-            {
-                if (it.data().second == Selected)
-                {
-                    QDate date(it.key(), 1, 1);
-                    QDateTime sdt(date);
-                    QDateTime edt = nextDateTime(sdt); 
-                    list.append(DateRange(sdt, edt));
-                    totalCount += it.data().first;
-                }
-            }
-            break;
-        }
     }
 
     DateRangeList::iterator it, it2;
+
     for (it = list.begin() ; it != list.end(); ++it)
         DDebug() << (*it).first.date().toString(Qt::ISODate) << " :: " 
                  << (*it).second.date().toString(Qt::ISODate) << endl;
 
     DDebug() << "Total Count of Items = " << totalCount << endl;
 
-    // Group contiguous date ranges to optimize query to database.
+    // Group contiguous date ranges to optimize query on database.
 
     DateRangeList list2;
     QDateTime     first, second;
@@ -1122,42 +1034,119 @@
     int day   = KGlobal::locale()->calendar()->dayOfYear(dt.date());
     int week  = KGlobal::locale()->calendar()->weekNumber(dt.date());
 
+    QMap<TimeLineWidgetPriv::YearRefPair, TimeLineWidgetPriv::StatPair>::iterator it;
+    QMap<int, TimeLineWidgetPriv::StatPair>::iterator it2;
+    QDateTime dts, dte;
+
     switch(d->dateMode)
     {
         case Day:
         {
-            QMap<TimeLineWidgetPriv::YearRefPair, TimeLineWidgetPriv::StatPair>::iterator it =
-                d->dayStatMap.find(TimeLineWidgetPriv::YearRefPair(year, day));
+            it = d->dayStatMap.find(TimeLineWidgetPriv::YearRefPair(year, day));
             if ( it != d->dayStatMap.end() )
                 it.data().second = selected;
             break;
         }
         case Week:
         {
-            QMap<TimeLineWidgetPriv::YearRefPair, TimeLineWidgetPriv::StatPair>::iterator it =
-                d->weekStatMap.find(TimeLineWidgetPriv::YearRefPair(year, week));
-            if ( it != d->weekStatMap.end() )
-                it.data().second = selected;
+            dts = firstDayOfWeek(year, week);
+            dte = dts.addDays(7);
+            setDaysRangeSelection(dts, dte, selected);
             break;
         }
         case Month:
         {
-            QMap<TimeLineWidgetPriv::YearRefPair, TimeLineWidgetPriv::StatPair>::iterator it =
-                d->monthStatMap.find(TimeLineWidgetPriv::YearRefPair(year, month));
-            if ( it != d->monthStatMap.end() )
-                it.data().second = selected;
+            dts = QDateTime(QDate(year, month, 1));
+            dte = dts.addDays(KGlobal::locale()->calendar()->daysInMonth(dts.date()));
+            setDaysRangeSelection(dts, dte, selected);
             break;
         }
         case Year:
         {
-            QMap<int, TimeLineWidgetPriv::StatPair>::iterator it = d->yearStatMap.find(year);
-            if ( it != d->yearStatMap.end() )
-                it.data().second = selected;
+            dts = QDateTime(QDate(year, 1, 1));
+            dte = dts.addDays(KGlobal::locale()->calendar()->daysInYear(dts.date()));
+            setDaysRangeSelection(dts, dte, selected);
             break;
         }
     }
+
+    // Update Week stats map
+
+    dts = firstDayOfWeek(year, week);
+    dte = dts.addDays(7);
+    it  = d->weekStatMap.find(TimeLineWidgetPriv::YearRefPair(year, week));
+    if ( it != d->weekStatMap.end() )
+        it.data().second = checkDaysRangeForSelection(dts, dte);
+
+    // Update Month stats map
+
+    dts = QDateTime(QDate(year, month, 1));
+    dte = dts.addDays(KGlobal::locale()->calendar()->daysInMonth(dts.date()));
+    it = d->monthStatMap.find(TimeLineWidgetPriv::YearRefPair(year, month));
+    if ( it != d->monthStatMap.end() )
+        it.data().second = checkDaysRangeForSelection(dts, dte);
+
+    // Update Year stats map
+
+    dts = QDateTime(QDate(year, 1, 1));
+    dte = dts.addDays(KGlobal::locale()->calendar()->daysInYear(dts.date()));
+    it2 = d->yearStatMap.find(year);
+    if ( it2 != d->yearStatMap.end() )
+        it2.data().second = checkDaysRangeForSelection(dts, dte);
 }
 
+void TimeLineWidget::setDaysRangeSelection(const QDateTime dts, const QDateTime dte, SelectionMode selected)
+{
+    int year, day;
+    QDateTime dt = dts;
+    QMap<TimeLineWidgetPriv::YearRefPair, TimeLineWidgetPriv::StatPair>::iterator it;
+
+    do
+    {
+        year = dt.date().year();
+        day  = KGlobal::locale()->calendar()->dayOfYear(dt.date());
+        it = d->dayStatMap.find(TimeLineWidgetPriv::YearRefPair(year, day));
+        if ( it != d->dayStatMap.end() )
+            it.data().second = selected;
+
+        dt = dt.addDays(1);
+    }
+    while(dt <= dte);
+}
+
+TimeLineWidget::SelectionMode TimeLineWidget::checkDaysRangeForSelection(const QDateTime dts, const QDateTime dte)
+{
+    int year, day;
+    int delta         = dts.daysTo(dte);
+    int count         = 0;
+    SelectionMode sel = Unselected;
+    QDateTime dt      = dts;
+    QMap<TimeLineWidgetPriv::YearRefPair, TimeLineWidgetPriv::StatPair>::iterator it;
+
+    do
+    {
+        year = dt.date().year();
+        day  = KGlobal::locale()->calendar()->dayOfYear(dt.date());
+
+        it = d->dayStatMap.find(TimeLineWidgetPriv::YearRefPair(year, day));
+        if ( it != d->dayStatMap.end() )
+        {
+            if (it.data().second != Unselected)
+            {
+                sel = FuzzySelection;
+                count++;
+            }
+        }
+        dt = dt.addDays(1);
+    }
+    while (dt <= dte);
+
+    if (count == delta)
+        sel = Selected;
+
+    return sel;
+}
+
 void TimeLineWidget::paintEvent(QPaintEvent*)
 {
     bitBlt(this, 0, 0, &d->pixmap);
@@ -1484,6 +1473,7 @@
             return dt;
         }
     }
+
     return QDateTime();
 }
 
--- branches/extragear/kde3/graphics/digikam/digikam/timelinewidget.h #759897:759898
@@ -85,12 +85,10 @@
 
     int cursorInfo(QDateTime& start, QDateTime& end);
 
+    /** Return a list of Date-Range based on selection performed on days-map */
+    DateRangeList selectedDateRange(int& totalCoun);
     void setSelectedDateRange(const DateRangeList& list);
-    DateRangeList selectedDateRange(int& totalCoun);
 
-    void resetSelection();
-    void resetAllSelection();
-
     int  totalIndex();
     int  indexForRefDateTime();
     void setCurrentIndex(int index);
@@ -109,31 +107,35 @@
     void slotNext();
     void slotBackward();
     void slotForward();
+    void slotResetSelection();
 
 private:
 
-    QDateTime prevDateTime(const QDateTime& dt);
-    QDateTime nextDateTime(const QDateTime& dt);
+    QDateTime     prevDateTime(const QDateTime& dt);
+    QDateTime     nextDateTime(const QDateTime& dt);
 
-    int       maxCount();
-    int       indexForDateTime(const QDateTime& date);
-    int       statForDateTime(const QDateTime& dt, SelectionMode& selected);
-    void      setDateTimeSelected(const QDateTime& dt, SelectionMode selected);
-    void      resetSelection(TimeLineWidget::DateMode mode);
-    void      setRefDateTime(const QDateTime& dateTime);
+    int           maxCount();
+    int           indexForDateTime(const QDateTime& date);
+    int           statForDateTime(const QDateTime& dt, SelectionMode& selected);
+    void          setRefDateTime(const QDateTime& dateTime);
 
-    void      updatePixmap();
-    void      paintEvent(QPaintEvent*);
-    void      resizeEvent(QResizeEvent*);
-    void      wheelEvent(QWheelEvent*); 
+    void          updatePixmap();
+    void          paintEvent(QPaintEvent*);
+    void          resizeEvent(QResizeEvent*);
+    void          wheelEvent(QWheelEvent*); 
 
-    void      mousePressEvent(QMouseEvent*);
-    void      mouseMoveEvent(QMouseEvent*);
-    void      mouseReleaseEvent(QMouseEvent*);
+    void          mousePressEvent(QMouseEvent*);
+    void          mouseMoveEvent(QMouseEvent*);
+    void          mouseReleaseEvent(QMouseEvent*);
 
-    QDateTime dateTimeForPoint(const QPoint& pt, bool &isOnSelectionArea);
-    QDateTime firstDayOfWeek(int year, int weekNumber);
+    QDateTime     dateTimeForPoint(const QPoint& pt, bool &isOnSelectionArea);
+    QDateTime     firstDayOfWeek(int year, int weekNumber);
 
+    void          resetSelection();
+    void          setDateTimeSelected(const QDateTime& dt, SelectionMode selected);
+    void          setDaysRangeSelection(const QDateTime dts, const QDateTime dte, SelectionMode selected);
+    SelectionMode checkDaysRangeForSelection(const QDateTime dts, const QDateTime dte);
+
 private:
 
     TimeLineWidgetPriv* d;


More information about the Digikam-devel mailing list