[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kphotoalbum] /: Show age of people on the images
From: Jesper K. Pedersen <blackie () kde ! org>
Date: 2014-07-31 17:21:14
Message-ID: E1XCu2U-0006k8-EM () scm ! kde ! org
[Download RAW message or body]
Git commit fd04e4776aec6f075984126fe2f41b683a30fe6c by Jesper K. Pedersen.
Committed on 31/07/2014 at 17:20.
Pushed by blackie into branch 'master'.
Show age of people on the images
M +2 -0 CMakeLists.txt
M +3 -0 ChangeLog
M +3 -1 DB/Category.h
A +150 -0 MainWindow/BirthDatesDialog.cpp [License: UNKNOWN] *
A +40 -0 MainWindow/BirthDatesDialog.h [License: UNKNOWN] *
A +32 -0 MainWindow/CalendarPopup.cpp [License: UNKNOWN] *
A +29 -0 MainWindow/CalendarPopup.h [License: UNKNOWN] *
M +10 -0 MainWindow/Window.cpp
M +1 -0 MainWindow/Window.h
M +91 -5 Utilities/Util.cpp
M +1 -0 Utilities/Util.h
M +3 -0 XMLDB/FileReader.cpp
M +3 -0 XMLDB/FileWriter.cpp
M +10 -0 XMLDB/XMLCategory.cpp
M +3 -0 XMLDB/XMLCategory.h
M +2 -1 kphotoalbumui.rc
The files marked with a * at the end have a non valid license. Please read: \
http://techbase.kde.org/Policies/Licensing_Policy and use the headers which are \
listed at that page.
http://commits.kde.org/kphotoalbum/fd04e4776aec6f075984126fe2f41b683a30fe6c
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6ff861e..c4c06d2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -223,6 +223,8 @@ set(libMainWindow_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/MainWindow/DuplicateMerger/DuplicateMatch.cpp
${CMAKE_CURRENT_SOURCE_DIR}/MainWindow/DuplicateMerger/MergeToolTip.cpp
${CMAKE_CURRENT_SOURCE_DIR}/MainWindow/CopyPopup.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/MainWindow/BirthDatesDialog.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/MainWindow/CalendarPopup.cpp
)
set(libImageManager_SRCS
diff --git a/ChangeLog b/ChangeLog
index 9232df2..7e32638 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+* New Feature: Specify the birth date for people (or any other category item for \
that matter) in Maintanence->Edit Birth Dates, + and see their age when viewing \
images. +
====================== KPhotoalbum 4.5 released ======================
* New Feature: Added an Android client, which can display images from
diff --git a/DB/Category.h b/DB/Category.h
index 6d09ba5..b129495 100644
--- a/DB/Category.h
+++ b/DB/Category.h
@@ -23,6 +23,7 @@
#include <qobject.h>
#include <ksharedptr.h>
#include "kiconloader.h"
+#include <QDate>
class QImage;
class QPixmap;
@@ -78,7 +79,8 @@ public:
QPixmap categoryImage( const QString& category, QString, int width, int height ) \
const;
void setCategoryImage( const QString& category, QString, const QImage& image );
QString fileForCategoryImage ( const QString& category, QString member ) const;
-
+ virtual void setBirthDate(const QString& item, const QDate& birthDate) = 0;
+ virtual QDate birthDate(const QString& item) const = 0;
private:
QString defaultIconName() const;
diff --git a/MainWindow/BirthDatesDialog.cpp b/MainWindow/BirthDatesDialog.cpp
new file mode 100644
index 0000000..e0de8c2
--- /dev/null
+++ b/MainWindow/BirthDatesDialog.cpp
@@ -0,0 +1,150 @@
+#include "BirthDatesDialog.h"
+#include <KLocale>
+#include <QComboBox>
+#include <QLabel>
+#include <QVBoxLayout>
+#include "DB/ImageDB.h"
+#include "DB/CategoryCollection.h"
+#include "DB/Category.h"
+#include <QPushButton>
+#include <QScrollArea>
+#include "CalendarPopup.h"
+#include <QLineEdit>
+#include <QShortcut>
+#include "DirtyIndicator.h"
+
+namespace MainWindow {
+
+BirthDatesDialog::BirthDatesDialog(QWidget *parent) :
+ QDialog(parent)
+{
+ setWindowTitle(i18n("Configure Birth Dates"));
+ QVBoxLayout* vlay = new QVBoxLayout(this);
+
+ QString txt = i18n("Set the date of birth for items (say people) here,\nand then \
see their age when viewing the images."); + QLabel* label = new QLabel(txt);
+ QFont fnt;
+ fnt.setPixelSize(20);
+ label->setFont(fnt);
+ label->setAlignment(Qt::AlignHCenter);
+ vlay->addWidget(label);
+ vlay->addSpacing(20);
+
+ QHBoxLayout* hlay = new QHBoxLayout;
+ vlay->addLayout(hlay);
+
+ QLabel* categoryText = new QLabel(i18n("Current Category"));
+ m_categoryBox = new QComboBox;
+
+ m_filter = new QLineEdit;
+ m_filter->setPlaceholderText(i18n("Filter (Alt+f)"));
+ new QShortcut(Qt::AltModifier + Qt::Key_F, m_filter, SLOT(setFocus()));
+
+ connect(m_filter,SIGNAL(textChanged(QString)), this, SLOT(resetCategory()));
+
+ hlay->addWidget(categoryText);
+ hlay->addWidget(m_categoryBox);
+ hlay->addSpacing(100);
+ hlay->addWidget(m_filter,1);
+
+ m_area = new QScrollArea;
+ m_area->setWidgetResizable(true);
+ vlay->addWidget(m_area);
+
+ QPushButton* close = new QPushButton(i18n("Close"));
+ connect(close, SIGNAL(clicked()), this, SLOT(accept()));
+ hlay = new QHBoxLayout;
+ vlay->addLayout(hlay);
+
+ hlay->addStretch(1);
+ hlay->addWidget(close);
+
+ int defaultIndex = 0;
+ int index = 0;
+ for (const DB::CategoryPtr& category: \
DB::ImageDB::instance()->categoryCollection()->categories()) { + \
if(!category->isSpecialCategory()) { + \
m_categoryBox->addItem(category->text(), category->name()); + if ( \
category->name() == QString::fromUtf8("Persons")) + defaultIndex = \
index; + ++index;
+ }
+ }
+
+ connect(m_categoryBox,SIGNAL(currentIndexChanged(int)),this,SLOT(changeCategory(int)));
+ m_categoryBox->setCurrentIndex(defaultIndex);
+ changeCategory(defaultIndex); // needed in case we didn't find the people \
category, to ensure the list is filled. +}
+
+QSize BirthDatesDialog::sizeHint() const
+{
+ return QSize(800,800);
+}
+
+void BirthDatesDialog::changeCategory(int index)
+{
+ QWidget* widget = new QWidget;
+ QGridLayout* grid = new QGridLayout(widget);
+ grid->setColumnStretch(2,1);
+
+ int row = 0;
+ const QString categoryName = m_categoryBox->itemData(index).value<QString>();
+ const DB::CategoryPtr category = \
DB::ImageDB::instance()->categoryCollection()->categoryForName(categoryName); + \
QStringList items = category->items(); + items.sort();
+ for (const QString& text : items) {
+ if (!m_filter->text().isEmpty() && text.indexOf(m_filter->text(), 0, \
Qt::CaseInsensitive) == -1) + continue;
+
+ QLabel* label = new QLabel(text);
+ const QDate date = category->birthDate(text);
+ QPushButton* button = new QPushButton(textForDate(date));
+ button->setProperty("date", date);
+ button->setProperty("name", text);
+ connect(button,SIGNAL(clicked()),this,SLOT(editDate()));
+ grid->addWidget(label,row,0);
+ grid->addWidget(button,row,1);
+ ++row;
+ }
+ grid->setRowStretch(row,1);
+
+ m_area->setWidget(widget);
+ widget->show();
+}
+
+void BirthDatesDialog::resetCategory()
+{
+ changeCategory(m_categoryBox->currentIndex());
+}
+
+void BirthDatesDialog::editDate()
+{
+ if (!m_datePick) {
+ m_datePick = new CalendarPopup;
+ connect(m_datePick,SIGNAL(dateSelected(QDate)), this, SLOT(setDate(QDate)));
+ }
+ m_editButton = static_cast<QPushButton*>(sender());
+ m_datePick->move(m_editButton->mapToGlobal(QPoint(0,0))-QPoint(m_datePick->sizeHint().width()/2, \
m_datePick->sizeHint().height()/2)); + \
m_datePick->setSelectedDate(m_editButton->property("date").value<QDate>()); + \
m_datePick->show(); +}
+
+void BirthDatesDialog::setDate(const QDate& date)
+{
+ m_datePick->hide();
+ m_editButton->setText(textForDate(date));
+ m_editButton->setProperty("date", date);
+
+ DB::CategoryPtr category = \
DB::ImageDB::instance()->categoryCollection()->categoryForName(m_categoryBox->itemData(m_categoryBox->currentIndex()).value<QString>());
+ DirtyIndicator::markDirty();
+ category->setBirthDate(m_editButton->property("name").value<QString>(), date);
+}
+
+QString BirthDatesDialog::textForDate(const QDate &date) const
+{
+ if (date.isNull())
+ return QString::fromUtf8("---");
+ else
+ return KGlobal::locale()->formatDate(date, KLocale::ShortDate);
+}
+
+} // namespace Settings
diff --git a/MainWindow/BirthDatesDialog.h b/MainWindow/BirthDatesDialog.h
new file mode 100644
index 0000000..2cec58d
--- /dev/null
+++ b/MainWindow/BirthDatesDialog.h
@@ -0,0 +1,40 @@
+#ifndef SETTINGS_BIRTHDAYPAGE_H
+#define SETTINGS_BIRTHDAYPAGE_H
+
+#include <QDialog>
+class QComboBox;
+class QLabel;
+class QPushButton;
+class QVBoxLayout;
+class QScrollArea;
+class QDate;
+class QLineEdit;
+
+namespace MainWindow {
+class CalendarPopup;
+
+class BirthDatesDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit BirthDatesDialog(QWidget *parent = 0);
+ QSize sizeHint() const;
+
+private slots:
+ void changeCategory(int index);
+ void resetCategory();
+ void editDate();
+ void setDate(const QDate&);
+
+private:
+ QString textForDate(const QDate& date) const;
+ QComboBox* m_categoryBox;
+ QScrollArea* m_area;
+ CalendarPopup* m_datePick = nullptr;
+ QPushButton* m_editButton;
+ QLineEdit* m_filter;
+};
+
+} // namespace Settings
+
+#endif // SETTINGS_BIRTHDAYPAGE_H
diff --git a/MainWindow/CalendarPopup.cpp b/MainWindow/CalendarPopup.cpp
new file mode 100644
index 0000000..52ab310
--- /dev/null
+++ b/MainWindow/CalendarPopup.cpp
@@ -0,0 +1,32 @@
+#include "CalendarPopup.h"
+
+#include <QCalendarWidget>
+#include <QPushButton>
+#include <QVBoxLayout>
+#include <KLocale>
+
+namespace MainWindow {
+
+CalendarPopup::CalendarPopup(QWidget *parent) :
+ QWidget(parent)
+{
+ setWindowFlags(Qt::Popup);
+
+ QVBoxLayout* vlay = new QVBoxLayout(this);
+
+ m_calendar = new QCalendarWidget;
+ vlay->addWidget(m_calendar);
+
+ QPushButton* button = new QPushButton(i18n("unset"));
+ vlay->addWidget(button);
+
+ connect(m_calendar, SIGNAL(clicked(QDate)), this, SIGNAL(dateSelected(QDate)));
+ connect(button, SIGNAL(clicked()), this, SIGNAL(dateSelected()));
+}
+
+void CalendarPopup::setSelectedDate(const QDate& date)
+{
+ m_calendar->setSelectedDate(date);
+}
+
+} // namespace Settings
diff --git a/MainWindow/CalendarPopup.h b/MainWindow/CalendarPopup.h
new file mode 100644
index 0000000..56496e4
--- /dev/null
+++ b/MainWindow/CalendarPopup.h
@@ -0,0 +1,29 @@
+#ifndef SETTINGS_CALENDARPOPUP_H
+#define SETTINGS_CALENDARPOPUP_H
+
+#include <QWidget>
+#include <QDate>
+
+class QCalendarWidget;
+
+namespace MainWindow {
+
+class CalendarPopup : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit CalendarPopup(QWidget *parent = 0);
+ void setSelectedDate(const QDate&);
+
+signals:
+ void dateSelected(const QDate& date = QDate());
+
+private:
+ void resetDate();
+
+ QCalendarWidget* m_calendar;
+};
+
+} // namespace Settings
+
+#endif // SETTINGS_CALENDARPOPUP_H
diff --git a/MainWindow/Window.cpp b/MainWindow/Window.cpp
index c397bb1..cc8eaba 100644
--- a/MainWindow/Window.cpp
+++ b/MainWindow/Window.cpp
@@ -101,6 +101,7 @@
# include "Exif/Database.h"
#endif
+#include "BirthDatesDialog.h"
#include "FeatureDialog.h"
#include <krun.h>
@@ -869,6 +870,9 @@ void MainWindow::Window::setupMenuBar()
_AutoStackImages = actionCollection()->addAction( QString::fromLatin1( \
"autoStack" ), this, SLOT (slotAutoStackImages()) );
_AutoStackImages->setText( i18n("Automatically Stack Selected Images...") );
+ KAction* editBirthDates = actionCollection()->addAction( \
QString::fromUtf8("editBirthDates"), this, SLOT(editBirthDates())); + \
editBirthDates->setText(i18n("Edit Birth Dates...")); +
a = actionCollection()->addAction( QString::fromLatin1("buildThumbs"), this, \
SLOT(slotBuildThumbnails()) ); a->setText( i18n("Build Thumbnails") );
@@ -1763,6 +1767,12 @@ void MainWindow::Window::mergeDuplicates()
merger->show();
}
+void MainWindow::Window::editBirthDates()
+{
+ MainWindow::BirthDatesDialog dialog;
+ dialog.exec();
+}
+
void MainWindow::Window::createSarchBar()
{
// Set up the search tool bar
diff --git a/MainWindow/Window.h b/MainWindow/Window.h
index 04b9cfc..3fb8a66 100644
--- a/MainWindow/Window.h
+++ b/MainWindow/Window.h
@@ -157,6 +157,7 @@ protected slots:
void useNextVideoThumbnail();
void usePreviousVideoThumbnail();
void mergeDuplicates();
+ void editBirthDates();
protected:
void configureImages( bool oneAtATime );
diff --git a/Utilities/Util.cpp b/Utilities/Util.cpp
index b2c0179..c918324 100644
--- a/Utilities/Util.cpp
+++ b/Utilities/Util.cpp
@@ -137,24 +137,25 @@ QString Utilities::createInfoText( DB::ImageInfoPtr info, QMap< \
int,QPair<QStrin
const StringSet items = info->itemsOfCategory( categoryName );
if (!items.empty()) {
QString title = QString::fromLatin1( "<b>%1: </b> " ).arg( \
(*categoryIt)->text() );
- QString info;
+ QString infoText;
bool first = true;
for( StringSet::const_iterator it2 = items.constBegin(); it2 != \
items.constEnd(); ++it2 ) { QString item = *it2;
if ( first )
first = false;
else
- info += QString::fromLatin1( ", " );
+ infoText += QString::fromLatin1( ", " );
if ( linkMap ) {
++link;
(*linkMap)[link] = QPair<QString,QString>( categoryName, \
item );
- info += QString::fromLatin1( "<a href=\"%1\">%2</a>").arg( \
link ).arg( item ); + infoText += QString::fromLatin1( "<a \
href=\"%1\">%2</a>").arg( link ).arg( item ); + infoText += \
formatAge(*categoryIt, item, info); }
else
- info += item;
+ infoText += item;
}
- AddNonEmptyInfo(title, info, &result);
+ AddNonEmptyInfo(title, infoText, &result);
}
}
}
@@ -210,6 +211,91 @@ QString Utilities::createInfoText( DB::ImageInfoPtr info, QMap< \
int,QPair<QStrin return result;
}
+using DateSpec = QPair<int, char>;
+DateSpec dateDiff(const QDate& birthDate, const QDate& imageDate)
+{
+ const int bday = birthDate.day();
+ const int iday = imageDate.day();
+ const int bmonth = birthDate.month();
+ const int imonth = imageDate.month();
+ const int byear = birthDate.year();
+ const int iyear = imageDate.year();
+
+ // Image before birth
+ const int diff = birthDate.daysTo(imageDate);
+ if (diff < 0)
+ return qMakePair(0, 'I');
+
+ if (diff < 31)
+ return qMakePair(diff, 'D');
+
+ int months = (iyear-byear)*12;
+ months += (imonth-bmonth);
+ months += (iday >= bday) ? 0 : -1;
+
+ if ( months < 24)
+ return qMakePair(months, 'M');
+ else
+ return qMakePair(months/12, 'Y');
+}
+
+QString formatDate(const DateSpec& date)
+{
+ if (date.second == 'I')
+ return {};
+ else if (date.second == 'D')
+ return i18np("1 day", "%1 days", date.first);
+ else if (date.second == 'M')
+ return i18np("1 month", "%1 month", date.first);
+ else
+ return i18np("1 year", "%1 years", date.first);
+}
+
+void test() {
+ Q_ASSERT(formatDate(dateDiff(QDate(1971,7,11), QDate(1971,7,11))) == \
QString::fromLatin1("0 days")); + Q_ASSERT(formatDate(dateDiff(QDate(1971,7,11), \
QDate(1971,8,10))) == QString::fromLatin1("30 days")); + \
Q_ASSERT(formatDate(dateDiff(QDate(1971,7,11), QDate(1971,8,11))) == \
QString::fromLatin1("1 month")); + Q_ASSERT(formatDate(dateDiff(QDate(1971,7,11), \
QDate(1971,8,12))) == QString::fromLatin1("1 month")); + \
Q_ASSERT(formatDate(dateDiff(QDate(1971,7,11), QDate(1971,9,10))) == \
QString::fromLatin1("1 month")); + Q_ASSERT(formatDate(dateDiff(QDate(1971,7,11), \
QDate(1971,9,11))) == QString::fromLatin1("2 month")); + \
Q_ASSERT(formatDate(dateDiff(QDate(1971,7,11), QDate(1972,6,10))) == \
QString::fromLatin1("10 month")); + Q_ASSERT(formatDate(dateDiff(QDate(1971,7,11), \
QDate(1972,6,11))) == QString::fromLatin1("11 month")); + \
Q_ASSERT(formatDate(dateDiff(QDate(1971,7,11), QDate(1972,6,12))) == \
QString::fromLatin1("11 month")); + Q_ASSERT(formatDate(dateDiff(QDate(1971,7,11), \
QDate(1972,7,10))) == QString::fromLatin1("11 month")); + \
Q_ASSERT(formatDate(dateDiff(QDate(1971,7,11), QDate(1972,7,11))) == \
QString::fromLatin1("12 month")); + Q_ASSERT(formatDate(dateDiff(QDate(1971,7,11), \
QDate(1972,7,12))) == QString::fromLatin1("12 month")); + \
Q_ASSERT(formatDate(dateDiff(QDate(1971,7,11), QDate(1972,12,11))) == \
QString::fromLatin1("17 month")); + Q_ASSERT(formatDate(dateDiff(QDate(1971,7,11), \
QDate(1973,7,11))) == QString::fromLatin1("2 years")); +}
+
+QString Utilities::formatAge(DB::CategoryPtr category, const QString &item, \
DB::ImageInfoPtr info) +{
+ // test(); // I wish I could get my act together to set up a test suite.
+ const QDate birthDate = category->birthDate(item);
+ const QDate start = info->date().start().date();
+ const QDate end = info->date().end().date();
+
+ if (birthDate.isNull() || start.isNull())
+ return {};
+
+ if ( start == end)
+ return QString::fromUtf8(" (%1)").arg(formatDate(dateDiff(birthDate, \
start))); + else {
+ DateSpec lower = dateDiff(birthDate,start);
+ DateSpec upper = dateDiff(birthDate,end);
+ if (lower == upper)
+ return QString::fromUtf8(" (%1)").arg(formatDate(lower));
+ else if (lower.second == 'I')
+ return QString::fromUtf8(" (< %1)").arg(formatDate(upper));
+ else {
+ if (lower.second == upper.second)
+ return QString::fromUtf8(" \
(%1-%2)").arg(lower.first).arg(formatDate(upper)); + else
+ return QString::fromUtf8(" \
(%1-%2)").arg(formatDate(lower)).arg(formatDate(upper)); + }
+ }
+}
+
void Utilities::checkForBackupFile( const QString& fileName, const QString& message \
) {
QString backupName = QFileInfo( fileName ).absolutePath() + \
QString::fromLatin1("/.#") + QFileInfo( fileName ).fileName();
diff --git a/Utilities/Util.h b/Utilities/Util.h
index b6b4b03..df81c3e 100644
--- a/Utilities/Util.h
+++ b/Utilities/Util.h
@@ -37,6 +37,7 @@ namespace DB
namespace Utilities
{
QString createInfoText( DB::ImageInfoPtr info, QMap<int, QPair<QString,QString> >* \
); +QString formatAge(DB::CategoryPtr category,const QString& item, DB::ImageInfoPtr \
info); void checkForBackupFile( const QString& fileName, const QString& message = \
QString() ); bool ctrlKeyDown();
bool copy( const QString& from, const QString& to );
diff --git a/XMLDB/FileReader.cpp b/XMLDB/FileReader.cpp
index db9167f..faf67fb 100644
--- a/XMLDB/FileReader.cpp
+++ b/XMLDB/FileReader.cpp
@@ -167,6 +167,7 @@ void XMLDB::FileReader::loadCategories( ReaderPtr reader )
static QString _positionable_ = QString::fromUtf8("positionable");
static QString _value_ = QString::fromUtf8("value");
static QString _id_ = QString::fromUtf8("id");
+ static QString _birthDate_ = QString::fromUtf8("birthDate");
static QString _Categories_ = QString::fromUtf8("Categories");
static QString _Category_ = QString::fromUtf8("Category");
@@ -199,6 +200,8 @@ void XMLDB::FileReader::loadCategories( ReaderPtr reader )
int id = reader->attribute(_id_).toInt();
static_cast<XMLCategory*>(cat.data())->setIdMapping( value, id \
); }
+ if (reader->hasAttribute(_birthDate_))
+ \
cat->setBirthDate(value,QDate::fromString(reader->attribute(_birthDate_), \
Qt::ISODate)); items.append( value );
reader->readEndElement();
}
diff --git a/XMLDB/FileWriter.cpp b/XMLDB/FileWriter.cpp
index a57e184..ad9db75 100644
--- a/XMLDB/FileWriter.cpp
+++ b/XMLDB/FileWriter.cpp
@@ -129,6 +129,9 @@ void XMLDB::FileWriter::saveCategories( QXmlStreamWriter& writer \
)
writer.writeAttribute( QString::fromLatin1("value"), \
categoryName ); writer.writeAttribute( QString::fromLatin1( "id" ),
\
QString::number(static_cast<XMLCategory*>( category.data() )->idForName( categoryName \
) )); + QDate birthDate = category->birthDate(categoryName);
+ if (!birthDate.isNull())
+ writer.writeAttribute( QString::fromUtf8("birthDate"), \
birthDate.toString(Qt::ISODate) ); }
}
}
diff --git a/XMLDB/XMLCategory.cpp b/XMLDB/XMLCategory.cpp
index 66c171d..40f31d8 100644
--- a/XMLDB/XMLCategory.cpp
+++ b/XMLDB/XMLCategory.cpp
@@ -179,5 +179,15 @@ void XMLDB::XMLCategory::setShouldSave( bool b)
_shouldSave = b;
}
+void XMLDB::XMLCategory::setBirthDate(const QString &item, const QDate &birthDate)
+{
+ _birthDates.insert(item,birthDate);
+}
+
+QDate XMLDB::XMLCategory::birthDate(const QString &item) const
+{
+ return _birthDates[item];
+}
+
#include "XMLCategory.moc"
// vi:expandtab:tabstop=4 shiftwidth=4:
diff --git a/XMLDB/XMLCategory.h b/XMLDB/XMLCategory.h
index fbb0e22..5128277 100644
--- a/XMLDB/XMLCategory.h
+++ b/XMLDB/XMLCategory.h
@@ -63,6 +63,8 @@ namespace XMLDB {
bool shouldSave();
void setShouldSave( bool b);
+ void setBirthDate(const QString& item, const QDate& birthDate) override;
+ QDate birthDate(const QString& item) const override;
private:
QString _name;
@@ -76,6 +78,7 @@ namespace XMLDB {
QStringList _items;
QMap<QString,int> _idMap;
QMap<int,QString> _nameMap;
+ QMap<QString,QDate> _birthDates;
bool _shouldSave;
};
diff --git a/kphotoalbumui.rc b/kphotoalbumui.rc
index c5cc996..2a19948 100644
--- a/kphotoalbumui.rc
+++ b/kphotoalbumui.rc
@@ -1,5 +1,5 @@
<!DOCTYPE kpartgui>
-<kpartgui name="kphotoalbum" version="41">
+<kpartgui name="kphotoalbum" version="42">
<MenuBar>
<Menu name="file">
<Action name="exportHTML"/>
@@ -62,6 +62,7 @@
<Action name="reReadExifInfo" />
<Action name="sortAllImages" />
<Action name="autoStack" />
+ <Action name="editBirthDates" />
<Separator/>
<Action name="removeAllThumbs"/>
<Action name="buildThumbs"/>
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic