Bug 135320

Summary: calendar year do not match locale
Product: [Applications] digikam Reporter: Orgad Shaneh <orgads>
Component: Plugin-Generic-CalendarAssignee: Digikam Developers <digikam-bugs-null>
Status: RESOLVED FIXED    
Severity: normal CC: imaging-bugs-null
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Fedora RPMs   
OS: Linux   
Latest Commit: Version Fixed In: 0.2.0
Sentry Crash Report:
Attachments: Calendar patch to any calendar type
fixed patch
fixed patch (forgot the underscore)
last patch (hopefully)

Description Orgad Shaneh 2006-10-09 09:03:32 UTC
Version:           0.8.2 (using KDE KDE 3.5.4)
Installed from:    Fedora RPMs
OS:                Linux

I'm using Hebrew calendar on my system. digikam handles it very well, but on Tools -> Create Calendar the months are the Hebrew calendar ones, but the year remains 2006 (and cannot be set to 5776, because in Gregorian dates it's after the range digikam can handle, latest year 3000).
Comment 1 caulier.gilles 2006-10-10 09:19:47 UTC
This tool is a kipi plugins.

Gilles
Comment 2 Orgad Shaneh 2006-10-10 15:55:39 UTC
yeah, I found out...
I'm trying to solve it by myself, but there are more problems - especially dealing with leap years (13 months).
I'll send a patch when I feel ready.
Comment 3 caulier.gilles 2006-10-10 15:59:42 UTC
Please, take a care than the patch mutch be created against svn trunk repository  implementation. Look here :

http://websvn.kde.org/trunk/extragear/libs/kipi-plugins/calendar/

Thanks in advance for your contribution.

Gilles Caulier
Comment 4 Orgad Shaneh 2006-10-11 08:40:07 UTC
Created attachment 18085 [details]
Calendar patch to any calendar type
Comment 5 Orgad Shaneh 2006-10-11 08:43:33 UTC
Comment on attachment 18085 [details]
Calendar patch to any calendar type

I assumed it's ok to use a static variable in a function (calselect.cpp
updateMonths).
I also saw usage of static variables in slideshow/slideshow.cpp and in
findimages/actions.cpp (sendMessage).
Comment 6 caulier.gilles 2006-10-11 08:46:48 UTC
Orgad,

We using static members in plugins using differents namespace wrapper to prevent memory problems between plugins. Just take a care about this point.

Gilles
Comment 7 Orgad Shaneh 2006-10-11 08:55:41 UTC
Created attachment 18086 [details]
fixed patch

no static variables
Comment 8 Orgad Shaneh 2006-10-11 09:26:13 UTC
Comment on attachment 18086 [details]
fixed patch

diff -pu calendar-bak/calpainter.cpp calendar/calpainter.cpp
--- calendar-bak/calpainter.cpp 2006-10-09 20:25:47.000000000 +0200
+++ calendar/calpainter.cpp	2006-10-09 22:10:52.000000000 +0200
@@ -91,13 +91,14 @@ void CalPainter::paint(bool useDeviceMet
     for (int i=0; i<42; i++)
	 days[i] = -1;

-    QDate d(year_, month_, 1);
+    QDate d;
+    KGlobal::locale()->calendar()->setYMD(d, year_, month_, 1);
     int s = d.dayOfWeek();

     if (s+7-startDayOffset >= 7)
	     s=s-7;

-    for (int i=s; i<(s+d.daysInMonth()); i++) {
+    for (int i=s; i<(s+KGlobal::locale()->calendar()->daysInMonth(d)); i++) {
	 days[i + (7-startDayOffset)] = i-s+1;
     }

@@ -317,13 +318,14 @@ void paintCalendar(int year, int month, 
     for (int i=0; i<42; i++)
	 days[i] = -1;

-    QDate d(year, month, 1);
+    QDate d;
+    KGlobal::locale()->calendar()->setYMD(d, year, month, 1);
     int s = d.dayOfWeek();

     if (s+7-startDayOffset >= 7)
	     s=s-7;

-    for (int i=s; i<(s+d.daysInMonth()); i++) {
+    for (int i=s; i<(s+KGlobal::locale()->calendar()->daysInMonth(d)); i++) {
	 days[i+(7-startDayOffset)] = i-s+1;
     }

@@ -549,13 +551,14 @@ CalBlockPainter::CalBlockPainter(QObject
     for (int i=0; i<42; i++)
	 days[i] = -1;

-    QDate d(year, month, 1);
+    QDate d;
+    KGlobal::locale()->calendar()->setYMD(d, year, month, 1);
     int s = d.dayOfWeek();

     if (s+7-startDayOffset >= 7)
	     s=s-7;

-    for (int i=s; i<(s+d.daysInMonth()); i++) {
+    for (int i=s; i<(s+KGlobal::locale()->calendar()->daysInMonth(d)); i++) {
	 days[i+(7-startDayOffset)] = i-s+1;
     }

diff -pu calendar-bak/calselect.cpp calendar/calselect.cpp
--- calendar-bak/calselect.cpp	2006-10-09 20:25:47.000000000 +0200
+++ calendar/calselect.cpp	2006-10-11 08:54:03.000000000 +0200
@@ -40,13 +40,17 @@
 #include "calsettings.h"
 #include "monthwidget.h"

+#define MAX_MONTHS (18)
+
 namespace KIPICalendarPlugin
 {

 CalSelect::CalSelect(KIPI::Interface* interface, QWidget *parent, const char*
name)
	  : QWidget(parent, name)
 {
-    mwVector_ = new QPtrVector<MonthWidget>(12);
+    mwVector_ = new QPtrVector<MonthWidget>(MAX_MONTHS);
+    monthBoxLayout_ = NULL;
+    totalMonths_ = 0;
     setupView( interface );
 }

@@ -88,8 +92,10 @@ void CalSelect::setupView( KIPI::Interfa
     yearBox->layout()->addItem(new QSpacerItem(5,5,
						QSizePolicy::Expanding,
						QSizePolicy::Minimum));
-    yearSpin_ = new QSpinBox(1900,3000,1,yearBox);
-    yearSpin_->setValue(QDate::currentDate().year());
+    yearSpin_ = new QSpinBox(KGlobal::locale()->calendar()->minValidYear(),
+			      KGlobal::locale()->calendar()->maxValidYear(),
+			      1,yearBox);
+   
yearSpin_->setValue(KGlobal::locale()->calendar()->year(QDate::currentDate()));
     slotYearChanged(yearSpin_->value());

     connect(yearSpin_, SIGNAL(valueChanged(int)),
@@ -106,8 +112,8 @@ void CalSelect::setupView( KIPI::Interfa
     monthBox->layout()->setSpacing( 6 );
     monthBox->layout()->setMargin( 11 );

-    QGridLayout *monthBoxLayout = new QGridLayout(monthBox->layout());
-    monthBoxLayout->setAlignment( Qt::AlignCenter );
+    monthBoxLayout_ = new QGridLayout(monthBox->layout());
+    monthBoxLayout_->setAlignment( Qt::AlignCenter );

     KURL::List urlList;
     KIPI::ImageCollection images = interface->currentSelection();
@@ -115,17 +121,14 @@ void CalSelect::setupView( KIPI::Interfa
	 urlList = images.images();

     MonthWidget *w;
-    int index = 0;
-    for (int i=0; i<2; i++) {
-	 for (int j=0; j<6; j++) {
-	     w = new MonthWidget( interface, monthBox,index+1);
-	     if (index < urlList.count())
-		 w->setImage(urlList[index]);
-	     mwVector_->insert(index,w);
-	     monthBoxLayout->addWidget(w, i, j);
-	     index++;
-	 }
+    for (int i=0; i<MAX_MONTHS; i++) {
+	 w = new MonthWidget( interface, monthBox, i+1);
+	 if (i < urlList.count())
+	     w->setImage(urlList[i]);
+	 w->hide(); // the needed months will be shown on updateMonths()
+	 mwVector_->insert(i, w);
     }
+    updateMonths();

     QLabel* tLabel =
	 new QLabel(i18n("Left click on Months to Select Images. "
@@ -133,7 +136,7 @@ void CalSelect::setupView( KIPI::Interfa
			 "You can also drag and drop images onto the Months"),
				 monthBox);

-    monthBoxLayout->addMultiCellWidget(tLabel, 2, 2, 0, 5);
+    monthBoxLayout_->addMultiCellWidget(tLabel, 2, 2, 0, 5);

     mainLayout->addWidget(monthBox);

@@ -143,9 +146,38 @@ void CalSelect::setupView( KIPI::Interfa
					 QSizePolicy::Expanding));
 }

+void CalSelect::updateMonths()
+{
+    int i;
+    QDate d;
+    KGlobal::locale()->calendar()->setYMD(d,
CalSettings::instance()->getYear(), 1, 1);
+
+    if (totalMonths_ != KGlobal::locale()->calendar()->monthsInYear(d) &&
!mwVector_->isEmpty())
+    {
+	 // hide the last months that are not present on the current year
+	 for (i=KGlobal::locale()->calendar()->monthsInYear(d);
(i<totalMonths_) && (i<mwVector_->count()); i++)
+	     mwVector_->at(i)->hide();
+
+	 // update totalMonths_ to current year's month count
+	 totalMonths_ = KGlobal::locale()->calendar()->monthsInYear(d);
+	 // span the monthWidgets over 2 rows. inRow should usually be 6 or 7
(for 12 or 13 months)
+	 int inRow = (totalMonths_ / 2) + ((totalMonths_ % 2) != 0);
+	 // remove all the monthWidgets, then readd the needed ones
+	 for (i=0; i<mwVector_->count(); i++) {
+	     monthBoxLayout_->remove(mwVector_->at(i));
+	 }
+	 for (i=0; (i<totalMonths_) && (i<mwVector_->count()); i++) {
+	     monthBoxLayout_->addWidget(mwVector_->at(i), i / inRow, i %
inRow);
+	     mwVector_->at(i)->show(); // in case it is hidden
+	     mwVector_->at(i)->repaint();
+	 }
+    }
+}
+
 void CalSelect::slotYearChanged(int year)
 {
     CalSettings::instance()->setYear(year);
+    updateMonths();
 }

 }  // NameSpace KIPICalendarPlugin
diff -pu calendar-bak/calselect.h calendar/calselect.h
--- calendar-bak/calselect.h	2006-10-09 20:25:47.000000000 +0200
+++ calendar/calselect.h	2006-10-11 08:53:32.000000000 +0200
@@ -50,9 +50,12 @@ public:
 private:

     void setupView( KIPI::Interface* interface );
+    void updateMonths();

     QPtrVector<MonthWidget> *mwVector_;
     QSpinBox		     *yearSpin_;
+    QGridLayout	     *monthBoxLayout_;
+    int		     totalMonths_;

 private slots:

diff -pu calendar-bak/calwidget.cpp calendar/calwidget.cpp
--- calendar-bak/calwidget.cpp	2006-10-09 20:25:47.000000000 +0200
+++ calendar/calwidget.cpp	2006-10-09 21:30:58.000000000 +0200
@@ -72,10 +72,10 @@ void CalWidget::recreate()
     if (!calPainter_)
	 calPainter_ = new CalPainter(pix_);

-    calPainter_->setYearMonth(QDate::currentDate().year(),
-			       QDate::currentDate().month());
+   
calPainter_->setYearMonth(KGlobal::locale()->calendar()->year(QDate::currentDat
e()),
+			      
KGlobal::locale()->calendar()->month(QDate::currentDate()));
     calPainter_->paint();
-    update();	  
+    update();
 }

 }  // NameSpace KIPICalendarPlugin
diff -pu calendar-bak/calwizard.cpp calendar/calwizard.cpp
--- calendar-bak/calwizard.cpp	2006-10-09 20:25:47.000000000 +0200
+++ calendar/calwizard.cpp	2006-10-10 16:37:43.000000000 +0200
@@ -220,9 +220,11 @@ void CalWizard::slotPageSelected(const Q
	 KURL image;
	 QString month;
	 QStringList printList;
-	 for (int i=1; i<=12; i++) {
+	 QDate d;
+	 KGlobal::locale()->calendar()->setYMD(d, cSettings_->getYear(), 1, 1);
+	 for (int i=1; i<=KGlobal::locale()->calendar()->monthsInYear(d); i++)
{
 #if KDE_IS_VERSION(3,2,0)
-	     month = KGlobal::locale()->calendar()->monthName(i, false);
+	     month = KGlobal::locale()->calendar()->monthName(i,
cSettings_->getYear(), false);
 #else
	     month = KGlobal::locale()->monthName(i);
 #endif
@@ -238,9 +240,9 @@ void CalWizard::slotPageSelected(const Q
	     QString year = QString::number(cSettings_->getYear());

	     QString extra;
-	     if ((QDate::currentDate().month() >= 6 &&
-		  QDate::currentDate().year() == cSettings_->getYear()) ||
-		 QDate::currentDate().year() > cSettings_->getYear())
+	     if ((KGlobal::locale()->calendar()->month(QDate::currentDate()) >=
6 &&
+		  KGlobal::locale()->calendar()->year(QDate::currentDate()) ==
cSettings_->getYear()) ||
+		 KGlobal::locale()->calendar()->year(QDate::currentDate()) >
cSettings_->getYear())
		 extra = "<br><br><b>"+i18n("Please note that you are making a
"
			 "calendar for<br>the current year or a year in the "
			 "past.")+"</b>";
@@ -342,7 +344,7 @@ void CalWizard::slotPrintOnePage()

 #if KDE_IS_VERSION(3,2,0)
     wFinishLabel_->setText(i18n("Printing Calendar Page for %1 of %2")
-		     .arg(KGlobal::locale()->calendar()->monthName(month,
false))
+		     .arg(KGlobal::locale()->calendar()->monthName(month,
cSettings_->getYear(), false))
		     .arg(yearName));
 #else
     wFinishLabel_->setText(i18n("Printing Calendar Page for %1 of %2")
diff -pu calendar-bak/monthwidget.cpp calendar/monthwidget.cpp
--- calendar-bak/monthwidget.cpp	2006-10-09 20:25:47.000000000 +0200
+++ calendar/monthwidget.cpp	2006-10-09 22:46:34.000000000 +0200
@@ -86,7 +86,7 @@ void MonthWidget::drawContents(QPainter 
 {

 #if KDE_IS_VERSION(3,2,0)
-    QString name = KGlobal::locale()->calendar()->monthName(month_, true);
+    QString name = KGlobal::locale()->calendar()->monthName(month_,
CalSettings::instance()->getYear(), true);
 #else
     QString name = KGlobal::locale()->monthName(month_, true);
 #endif
Comment 9 Orgad Shaneh 2006-10-11 09:29:03 UTC
Created attachment 18087 [details]
fixed patch (forgot the underscore)

I forgot to add an underscore to totalMonths (as a member variable).
sorry.
Comment 10 Orgad Shaneh 2006-10-11 12:11:08 UTC
Created attachment 18089 [details]
last patch (hopefully)

The member variable was not needed. I removed the additional function, and
added its contents to slotYearChanged() and part of it back to setupView().

More logical now...

and comment #8 was sent by mistake. please erase it.
Comment 11 caulier.gilles 2006-10-11 12:19:35 UTC
Thanks for the patch. we will check it for the the next release.

Gilles Caulier
Comment 12 Tom Albers 2006-10-12 18:44:33 UTC
Thanks Orgad, I will review next week, at first glance, it looks ok.
Comment 13 Orgad Shaneh 2006-10-12 21:44:59 UTC
The line:
int inRow = (totalMonths_ / 2) + ((totalMonths_ % 2) != 0);
at calselect.cpp can be replaced with:
int inRow = (int)ceil((double)totalMonths_ / 2.0);

I didn't check it yet (not home), but it should work.
(of course, #include <math.h> might be needed)
Comment 14 caulier.gilles 2008-12-07 21:39:28 UTC
Orgad,

What's about this file ? Still Valid ?

Gilles Caulier
Comment 15 Orgad Shaneh 2008-12-08 18:03:38 UTC
it is fixed