Skip to content

Commit

Permalink
cherry pick #1
Browse files Browse the repository at this point in the history
  • Loading branch information
Kicer86 committed Jun 13, 2021
1 parent 9b92e4e commit 4ca5726
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
struct IExifReader;


class SeriesDetector
class DATABASE_EXPORT SeriesDetector
{
public:
struct DATABASE_EXPORT Rules
Expand Down
3 changes: 3 additions & 0 deletions src/gui/desktop/models/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ set(SRC
model_types.hpp
notifications_model.cpp
notifications_model.hpp
series_model.cpp
series_model.hpp
)

source_group(files REGULAR_EXPRESSION .*gui.* )
Expand All @@ -19,6 +21,7 @@ target_link_libraries(gui_models
database
PRIVATE
core
project_utils
)

target_include_directories(gui_models
Expand Down
171 changes: 171 additions & 0 deletions src/gui/desktop/models/series_model.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@

#include <core/function_wrappers.hpp>
#include <core/iexif_reader.hpp>
#include <core/ilogger_factory.hpp>
#include <core/itask_executor.hpp>
#include <core/task_executor_utils.hpp>
#include <database/database_tools/implementation/series_detector.hpp>
#include <QElapsedTimer>
#include <QPromise>

#include "gui/desktop/utils/groups_manager.hpp"
#include "series_model.hpp"


using namespace std::placeholders;


SeriesModel::SeriesModel(Project& project, ICoreFactoryAccessor& core)
: m_logger(core.getLoggerFactory().get("SeriesModel"))
, m_project(project)
, m_core(core)
, m_initialized(false)
, m_loaded(false)
{

}


SeriesModel::~SeriesModel()
{
m_candidatesFuture.cancel();
m_candidatesFuture.waitForFinished();
}


bool SeriesModel::isLoaded() const
{
return m_loaded;
}


void SeriesModel::groupBut(const QSet<int>& excludedRows)
{
std::vector<GroupCandidate> toStore;

for(int i = 0; i < m_candidates.size(); i++)
{
if (excludedRows.contains(i))
continue;

const auto& candidate = m_candidates[i];
toStore.push_back(candidate);
}

auto& executor = m_core.getTaskExecutor();

for (const auto& group: toStore)
{
runOn(executor, [group, &project = m_project, &exifFactor = m_core.getExifReaderFactory()]() mutable
{
//GroupsManager::groupIntoCollage(project.getDatabase(), exifFactor, project, group.members);
},
"colage group generation");
}
}


QVariant SeriesModel::data(const QModelIndex& index, int role) const
{
if (index.isValid() && index.column() == 0 && index.row() < m_candidates.size())
{
const auto& candidate = m_candidates[index.row()];

if (role == PhotoDataRole)
return QVariant::fromValue(candidate.members.front());
else if (role == DetailsRole)
return QVariant::fromValue(candidate);
else if (role == GroupTypeRole)
{
QString type;
switch (candidate.type)
{
case Group::Type::Invalid: break;
case Group::Type::Animation: type = tr("Photo series"); break;
case Group::Type::HDR: type = tr("HDR"); break;
case Group::Type::Generic: type = tr("Photos taken at similar time"); break;
}

return type;
}
else if (role == MembersRole)
return QVariant::fromValue(candidate.members);
}

return {};
}


int SeriesModel::rowCount(const QModelIndex& parent) const
{
return m_candidates.size();
}


bool SeriesModel::canFetchMore(const QModelIndex& parent) const
{
return parent.isValid() == false && m_initialized == false;
}

void SeriesModel::fetchMore(const QModelIndex& parent)
{
if (parent.isValid() == false)
{
m_initialized = true;

fetchGroups();
}
}


QHash<int, QByteArray> SeriesModel::roleNames() const
{
auto roles = QAbstractListModel::roleNames();

roles.insert(
{
{ DetailsRole, "details" },
{ PhotoDataRole, "photoData" },
{ GroupTypeRole, "groupType" },
{ MembersRole, "members" }
});

return roles;
}


void SeriesModel::fetchGroups()
{
auto& executor = m_core.getTaskExecutor();

m_candidatesFuture = runOn<std::vector<GroupCandidate>>
(
executor,
[this](QPromise<std::vector<GroupCandidate>>& promise)
{
IExifReaderFactory& exif = m_core.getExifReaderFactory();

QElapsedTimer timer;

SeriesDetector detector(*m_project.getDatabase(), exif.get(), &promise);

timer.start();
promise.addResult(detector.listCandidates());
m_logger->debug(QString("Photos analysis took %1s").arg(timer.elapsed()/1000.0));
},
"SeriesDetector"
);

m_candidatesFuture.then(std::bind(&SeriesModel::updateModel, this, _1));
}


void SeriesModel::updateModel(const std::vector<GroupCandidate>& canditates)
{
beginInsertRows({}, 0, canditates.size() - 1);
m_candidates = canditates;
endInsertRows();

m_loaded = true;
emit loadedChanged(m_loaded);
}
57 changes: 57 additions & 0 deletions src/gui/desktop/models/series_model.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

#ifndef SERIESMODEL_HPP
#define SERIESMODEL_HPP

#include <QAbstractItemModel>
#include <QFuture>

#include <core/icore_factory_accessor.hpp>
#include <database/idatabase.hpp>
#include <database/database_tools/series_candidate.hpp>
#include <project_utils/project.hpp>

class SeriesDetector;

class SeriesModel: public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(bool loaded READ isLoaded NOTIFY loadedChanged)

public:
enum Roles
{
DetailsRole = Qt::UserRole + 1,
PhotoDataRole,
GroupTypeRole,
MembersRole,
};

SeriesModel(Project &, ICoreFactoryAccessor &);
~SeriesModel();

bool isLoaded() const;
Q_INVOKABLE void groupBut(const QSet<int> &);

QVariant data(const QModelIndex& index, int role) const override;
int rowCount(const QModelIndex& parent) const override;
bool canFetchMore(const QModelIndex& parent) const override;
void fetchMore(const QModelIndex& parent) override;
QHash<int, QByteArray> roleNames() const override;

signals:
void loadedChanged(bool) const;

private:
std::unique_ptr<ILogger> m_logger;
std::vector<GroupCandidate> m_candidates;
Project& m_project;
ICoreFactoryAccessor& m_core;
QFuture<std::vector<GroupCandidate>> m_candidatesFuture;
bool m_initialized;
bool m_loaded;

void fetchGroups();
void updateModel(const std::vector<GroupCandidate> &);
};

#endif
50 changes: 1 addition & 49 deletions src/gui/desktop/widgets/series_detection/series_detection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ SeriesDetection::SeriesDetection(Database::IDatabase* db,
IThumbnailsManager* thbMgr,
Project& project):
QDialog(),
m_seriesModel(*db, *core),
m_seriesModel(project, *core),
m_core(core),
m_db(db),
m_project(project),
Expand All @@ -70,10 +70,6 @@ SeriesDetection::SeriesDetection(Database::IDatabase* db,
layout->addWidget(m_qmlView);
layout->addWidget(dialog_buttons);

// wiring
QObject* seriesDetectionMainId = QmlUtils::findQmlObject(m_qmlView, "seriesDetectionMain");
connect(seriesDetectionMainId, SIGNAL(groupBut(QVariant)), this, SLOT(groupBut(QVariant)));

connect(dialog_buttons, &QDialogButtonBox::rejected, this, &QDialog::accept);
}

Expand All @@ -83,47 +79,3 @@ SeriesDetection::~SeriesDetection()
// delete qml view before all other objects it referes to will be deleted
delete m_qmlView;
}


void SeriesDetection::groupBut(const QVariant& rowsVariant)
{
const QJSValue rawValues = rowsVariant.value<QJSValue>();

QVector<int> excludedValues;
const int length = rawValues.property("length").toInt();
for (int i = 0; i < length; i++)
excludedValues.append(rawValues.property(i).toInt());

//const QModelIndex firstItemInRow = m_tabModel.index(row, 0);
//const GroupCandidate groupDetails = firstItemInRow.data(SeriesModel::DetailsRole).value<GroupCandidate>();
//launch_groupping_dialog(groupDetails);
}


void SeriesDetection::launch_groupping_dialog(const GroupCandidate& candidate)
{
auto logger = m_core->getLoggerFactory().get("PhotosGrouping");

PhotosGroupingDialog pgd(
candidate.members,
m_core->getExifReaderFactory(),
m_core->getTaskExecutor(),
m_core->getConfiguration(),
logger.get(),
candidate.type
);

const int exit_code = pgd.exec();

if (exit_code == QDialog::Accepted)
{
const auto representat = GroupsManager::copyRepresentatToDatabase(pgd.getRepresentative(), m_project);
GroupsManager::group(m_db, pgd.photos(), representat, pgd.groupType());
}
}


int SeriesDetection::selected_row() const
{
return 0;
}
8 changes: 2 additions & 6 deletions src/gui/desktop/widgets/series_detection/series_detection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@
#include <QQmlPropertyMap>

#include <core/ithumbnails_manager.hpp>
#include <database/database_tools/series_model.hpp>
#include <database/photo_data.hpp>

#include "quick_views/qml_setup.hpp"
#include "models/series_model.hpp"


class QStandardItemModel;
Expand Down Expand Up @@ -58,11 +59,6 @@ class SeriesDetection: public QDialog

void fetch_series(Database::IBackend &);
void load_series(const std::vector<GroupCandidate> &);
void launch_groupping_dialog(const GroupCandidate &);
int selected_row() const;

private slots:
void groupBut(const QVariant &);
};

#endif // SERIESDETECTION_HPP
3 changes: 3 additions & 0 deletions tr/photo_broom_en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -848,16 +848,19 @@ Error code: %1</source>
<name>SeriesModel</name>
<message>
<location filename="../src/database/database_tools/implementation/series_model.cpp" line="57"/>
<location filename="../src/gui/desktop/models/series_model.cpp" line="84"/>
<source>Photo series</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/database/database_tools/implementation/series_model.cpp" line="58"/>
<location filename="../src/gui/desktop/models/series_model.cpp" line="85"/>
<source>HDR</source>
<translation>HDR</translation>
</message>
<message>
<location filename="../src/database/database_tools/implementation/series_model.cpp" line="59"/>
<location filename="../src/gui/desktop/models/series_model.cpp" line="86"/>
<source>Photos taken at similar time</source>
<translation type="unfinished"></translation>
</message>
Expand Down
3 changes: 3 additions & 0 deletions tr/photo_broom_pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -870,16 +870,19 @@ Kod błędu: %1</translation>
<name>SeriesModel</name>
<message>
<location filename="../src/database/database_tools/implementation/series_model.cpp" line="+57"/>
<location filename="../src/gui/desktop/models/series_model.cpp" line="+84"/>
<source>Photo series</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
<location filename="../src/gui/desktop/models/series_model.cpp" line="+1"/>
<source>HDR</source>
<translation>HDR</translation>
</message>
<message>
<location line="+1"/>
<location filename="../src/gui/desktop/models/series_model.cpp" line="+1"/>
<source>Photos taken at similar time</source>
<translation type="unfinished"></translation>
</message>
Expand Down

0 comments on commit 4ca5726

Please sign in to comment.