From bfb9cf04c363d0c5ea3ba2da96863a89f626bfd1 Mon Sep 17 00:00:00 2001 From: b0dyless Date: Mon, 19 May 2025 16:57:12 +0200 Subject: [PATCH 01/32] Aggiunta interfaccia database --- src/Memory/Database.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/Memory/Database.h diff --git a/src/Memory/Database.h b/src/Memory/Database.h new file mode 100644 index 0000000..3406307 --- /dev/null +++ b/src/Memory/Database.h @@ -0,0 +1,21 @@ +#ifndef MEMORY_DATABASE_H +#define MEMORY_DATABASE_H +#include + +#include "./MediaContainer.h" + +namespace memory { +class Database { + private: + MediaContainer media_container_; + QFile db_file_; + + public: + Database() = default; + int open(const std::string &path); + int close(); + int save(); + std::vector filterMedia(const media::Media *) const; +}; +} // namespace memory +#endif From 8adc8662fe156d556b1e6bdebae3ea3c5cbaac72 Mon Sep 17 00:00:00 2001 From: Steva0 Date: Mon, 19 May 2025 17:14:36 +0200 Subject: [PATCH 02/32] Aggiunto tutti i gli operatori== --- .gitignore | 2 + src/Media/Album.cpp | 10 +++++ src/Media/Album.h | 1 + src/Media/AudioBook.cpp | 9 ++++- src/Media/AudioBook.h | 2 +- src/Media/Ebook.cpp | 11 ++++-- src/Media/Ebook.h | 2 +- src/Media/Media.cpp | 7 ++++ src/Media/Media.h | 2 + src/Media/Movie.cpp | 8 ++++ src/Media/Movie.h | 1 + src/Media/Novel.cpp | 11 ++++-- src/Media/Novel.h | 2 +- src/Media/Series.cpp | 8 ++++ src/Media/Series.h | 1 + src/Memory/MediaContainer.cpp | 71 +++++++++++++++++++++++++++++++++++ src/Memory/MediaContainer.h | 61 ++++++++++++++++++++++++------ 17 files changed, 187 insertions(+), 22 deletions(-) create mode 100644 src/Memory/MediaContainer.cpp diff --git a/.gitignore b/.gitignore index 771d7a4..bdb5fa1 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,8 @@ *.so.* *.dll *.dylib +build +checks.json # Qt-es object_script.*.Release diff --git a/src/Media/Album.cpp b/src/Media/Album.cpp index d20ecf3..4f3453c 100644 --- a/src/Media/Album.cpp +++ b/src/Media/Album.cpp @@ -16,4 +16,14 @@ const std::vector &Album::getBandMembers() const { return band_members_; } const std::vector &Album::getSongs() const { return songs_; } +bool Album::operator==(const Media &other) const { + const Album *other_album = dynamic_cast(&other); + if (other_album) { + return Media::operator==(*other_album) && band_ == other_album->band_ && + band_members_ == other_album->band_members_ && + songs_ == other_album->songs_; + } + return false; +} + } // namespace media diff --git a/src/Media/Album.h b/src/Media/Album.h index 99c802e..3839490 100644 --- a/src/Media/Album.h +++ b/src/Media/Album.h @@ -18,6 +18,7 @@ class Album : public Media { const std::string &getBand() const; const std::vector &getBandMembers() const; const std::vector &getSongs() const; + bool operator==(const Media &other) const override; }; } // namespace media #endif diff --git a/src/Media/AudioBook.cpp b/src/Media/AudioBook.cpp index b1aa6af..4a85455 100644 --- a/src/Media/AudioBook.cpp +++ b/src/Media/AudioBook.cpp @@ -12,8 +12,13 @@ AudioBook::AudioBook(const std::string& title, int publicationYear, const std::s narrator_(narrator), streamingService_(streamingService) {} -void AudioBook::accept(IConstMediaVisitor& v) const { - v.visit(*this); +bool AudioBook::operator==(const Media& other) const { + const AudioBook* otherAudioBook = dynamic_cast(&other); + if (otherAudioBook) { + return Novel::operator==(*otherAudioBook) && narrator_ == otherAudioBook->narrator_ && + streamingService_ == otherAudioBook->streamingService_; + } + return false; } std::string AudioBook::getNarrator() const { diff --git a/src/Media/AudioBook.h b/src/Media/AudioBook.h index ecb7c60..4b0bc09 100644 --- a/src/Media/AudioBook.h +++ b/src/Media/AudioBook.h @@ -17,7 +17,7 @@ class AudioBook : public Novel { unsigned int duration, const std::string& series, const std::string& isbn, const std::string& narrator, const std::string& streamingService); - void accept(IConstMediaVisitor& v) const override; + bool operator==(const Media& other) const override; std::string getNarrator() const; std::string getStreamingService() const; diff --git a/src/Media/Ebook.cpp b/src/Media/Ebook.cpp index 9a26700..c12bf2a 100644 --- a/src/Media/Ebook.cpp +++ b/src/Media/Ebook.cpp @@ -11,9 +11,14 @@ Ebook::Ebook(const std::string& title, int publicationYear, const std::string& l author, publisher, pages, series, isbn), fileSizeBytes_(fileSizeBytes), drm_(drm) {} -void Ebook::accept(IConstMediaVisitor& v) const { - v.visit(*this); -} +bool Ebook::operator==(const Media& other) const { + const Ebook* otherEbook = dynamic_cast(&other); + if (otherEbook) { + return Novel::operator==(*otherEbook) && fileSizeBytes_ == otherEbook->fileSizeBytes_ && + drm_ == otherEbook->drm_; + } + return false; +} unsigned int Ebook::getFileSizeBytes() const { return fileSizeBytes_; diff --git a/src/Media/Ebook.h b/src/Media/Ebook.h index 367f85b..7035703 100644 --- a/src/Media/Ebook.h +++ b/src/Media/Ebook.h @@ -17,7 +17,7 @@ class Ebook : public Novel { unsigned int pages, const std::string& series, const std::string& isbn, unsigned int fileSizeBytes, bool drm); - void accept(IConstMediaVisitor& v) const override; + bool operator==(const Media& other) const override; unsigned int getFileSizeBytes() const; bool hasDrm() const; diff --git a/src/Media/Media.cpp b/src/Media/Media.cpp index fbad213..9d732e6 100644 --- a/src/Media/Media.cpp +++ b/src/Media/Media.cpp @@ -14,6 +14,13 @@ Media::Media(const std::string &title, int release, const std::string &language, void Media::accept(IConstMediaVisitor &v) const {} +bool Media::operator==(const Media &other) const { + return title_ == other.title_ && release_ == other.release_ && + language_ == other.language_ && favourite_ == other.favourite_ && + genres_ == other.genres_ && img_path_ == other.img_path_ && + notes_ == other.notes_; +} + bool Media::open() { notes_ = ""; std::cout<< "Media::open()" << std::endl; diff --git a/src/Media/Media.h b/src/Media/Media.h index 2eb83c4..d743fe4 100644 --- a/src/Media/Media.h +++ b/src/Media/Media.h @@ -25,6 +25,8 @@ class Media : IMedia{ public: + virtual bool operator==(const Media &other) const; + void accept(IConstMediaVisitor &) const override; bool open() override; diff --git a/src/Media/Movie.cpp b/src/Media/Movie.cpp index 1e7a3a1..026eb63 100644 --- a/src/Media/Movie.cpp +++ b/src/Media/Movie.cpp @@ -10,6 +10,14 @@ Movie::Movie(const std::string &title, int release, const std::string &language, cast_(cast), length_(length), universe_(universe) {} +bool Movie::operator==(const Media &other) const { + const Movie *otherMovie = dynamic_cast(&other); + if (otherMovie) { + return Media::operator==(*otherMovie) && cast_ == otherMovie->cast_ && + length_ == otherMovie->length_ && universe_ == otherMovie->universe_; + } + return false; +} const std::vector &Movie::getCast() const { return cast_; } unsigned int Movie::getLength() const { return length_; } const std::string &Movie::getUniverse() const { return universe_; } diff --git a/src/Media/Movie.h b/src/Media/Movie.h index 9f23113..0c736dc 100644 --- a/src/Media/Movie.h +++ b/src/Media/Movie.h @@ -19,6 +19,7 @@ class Movie : public Media { const std::string &img_path, const std::string ¬es, const std::vector &cast, unsigned int length, const std::string &universe); + bool operator==(const Media &other) const override; const std::vector &getCast() const; unsigned int getLength() const; const std::string &getUniverse() const; diff --git a/src/Media/Novel.cpp b/src/Media/Novel.cpp index 2f21c7e..4c827d2 100644 --- a/src/Media/Novel.cpp +++ b/src/Media/Novel.cpp @@ -9,9 +9,14 @@ Novel::Novel(const std::string& title, int publicationYear, const std::string& l : Media(title, publicationYear, language, favorite, genres, imagePath, notes), author_(author), publisher_(publisher), pages_(pages), series_(series), isbn_(isbn) {} -// Visitor -void Novel::accept(IConstMediaVisitor& v) const { - v.visit(*this); +bool Novel::operator==(const Media& other) const { + const Novel* otherNovel = dynamic_cast(&other); + if (otherNovel) { + return Media::operator==(*otherNovel) && author_ == otherNovel->author_ && + publisher_ == otherNovel->publisher_ && pages_ == otherNovel->pages_ && + series_ == otherNovel->series_ && isbn_ == otherNovel->isbn_; + } + return false; } // Getters diff --git a/src/Media/Novel.h b/src/Media/Novel.h index 8462a61..a736000 100644 --- a/src/Media/Novel.h +++ b/src/Media/Novel.h @@ -19,7 +19,7 @@ class Novel : public Media { const std::string& author, const std::string& publisher, unsigned int pages, const std::string& series, const std::string& isbn); - void accept(IConstMediaVisitor& v) const override; + bool operator==(const Media& other) const override; // Getters std::string getAuthor() const; diff --git a/src/Media/Series.cpp b/src/Media/Series.cpp index fb6c2a5..4004f93 100644 --- a/src/Media/Series.cpp +++ b/src/Media/Series.cpp @@ -13,6 +13,14 @@ Series::Series(const std::string &title, int release, episodes_(episodes), seasons_(seasons), ended_(ended) {} +bool Series::operator==(const Media &other) const { + const Series *otherSeries = dynamic_cast(&other); + if (otherSeries) { + return Movie::operator==(*otherSeries) && episodes_ == otherSeries->episodes_ && + seasons_ == otherSeries->seasons_ && ended_ == otherSeries->ended_; + } + return false; +} unsigned int Series::getEpisodes() const { return episodes_; } unsigned int Series::getSeasons() const { return seasons_; } bool Series::isEnded() const { return ended_; } diff --git a/src/Media/Series.h b/src/Media/Series.h index 91b96b0..036086f 100644 --- a/src/Media/Series.h +++ b/src/Media/Series.h @@ -16,6 +16,7 @@ class Series : public Movie { const std::vector &cast, unsigned int length, const std::string &universe, unsigned int episodes, unsigned int seasons, bool ended); + bool operator==(const Media &other) const override; unsigned int getEpisodes() const; unsigned int getSeasons() const; bool isEnded() const; diff --git a/src/Memory/MediaContainer.cpp b/src/Memory/MediaContainer.cpp new file mode 100644 index 0000000..4fcd3aa --- /dev/null +++ b/src/Memory/MediaContainer.cpp @@ -0,0 +1,71 @@ +#include "MediaContainer.h" +namespace memory { + +void MediaContainer::addMedia(const std::shared_ptr& media) { + if (!media) return; + + data_[static_cast(MediaType::All)].push_back(media); + + MediaType type = determineType(media); + if (type != MediaType::All) { + data_[static_cast(type)].push_back(media); + } +} + +void MediaContainer::removeMedia(const std::shared_ptr& media) { + if (!media) return; + + for (auto& vec : data_) { + vec.erase(std::remove_if(vec.begin(), vec.end(), + [&](const std::shared_ptr& m) { + return typeid(*m) == typeid(*media) && *m == *media; + }), vec.end()); + } +} + +void MediaContainer::clear() { + for (auto& vec : data_) { + vec.clear(); + } +} + +std::vector> MediaContainer::filterByTitle(const std::string& title) const { + return filter([&](const media::Media& m) { + return m.getTitle() == title; + }); +} + +std::vector> MediaContainer::filterByYear(int year) const { + return filter([&](const media::Media& m) { + return m.getRelease() == year; + }); +} + +std::vector> MediaContainer::getAll() const { + return data_[static_cast(MediaType::All)]; +} + +std::vector> MediaContainer::getByType(MediaType type) const { + return data_[static_cast(type)]; +} + +std::vector> MediaContainer::filter(std::function predicate) const { + std::vector> result; + for (const auto& media : data_[static_cast(MediaType::All)]) { + if (predicate(*media)) { + result.push_back(media); + } + } + return result; +} + +MediaType MediaContainer::determineType(const std::shared_ptr& media) const { + if (std::dynamic_pointer_cast(media)) return MediaType::Series; + if (std::dynamic_pointer_cast(media)) return MediaType::Movie; + if (std::dynamic_pointer_cast(media)) return MediaType::AudioBook; + if (std::dynamic_pointer_cast(media)) return MediaType::EBook; + if (std::dynamic_pointer_cast(media)) return MediaType::Novel; + if (std::dynamic_pointer_cast(media)) return MediaType::Album; + return MediaType::All; +} +} \ No newline at end of file diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index cc24df4..72a17c5 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -1,14 +1,53 @@ -#ifndef MEMORY_MEDIA_CONTAINER_H -#define MEMORY_MEDIA_CONTAINER_H -#include "../Media/Media.h" +#ifndef MEMORY_MEDIACONTAINER_H +#define MEMORY_MEDIACONTAINER_H + +#include +#include +#include +#include +#include +#include + +#include "Media.h" +#include "Novel.h" +#include "Album.h" +#include "Movie.h" +#include "Ebook.h" +#include "AudioBook.h" +#include "Series.h" + +namespace memory{ + +enum class MediaType { + All = 0, + Novel, + Album, + Movie, + EBook, + AudioBook, + Series, + Count // serve per la dimensione dell’array +}; -namespace memory { class MediaContainer { - public: - MediaContainer() = default; - int addMedia(media::Media *); - int removeMedia(media::Media *); - std::vector filter(media::Media *); +private: + std::array>, static_cast(MediaType::Count)> data_; + + MediaType determineType(const std::shared_ptr& media) const; + +public: + void addMedia(const std::shared_ptr& media); + void removeMedia(const std::shared_ptr& media); + void clear(); + + std::vector> filterByTitle(const std::string& title) const; + std::vector> filterByYear(int year) const; + + std::vector> getAll() const; + std::vector> getByType(MediaType type) const; + + // Combinazioni di filtri + std::vector> filter(std::function predicate) const; }; -} // namespace memory -#endif +} +#endif // MEMORY_MEDIACONTAINER_H From 90b9ddb653fbbe8b8f4a9c8e20c4cbd46314ede1 Mon Sep 17 00:00:00 2001 From: b0dyless Date: Mon, 19 May 2025 19:32:04 +0200 Subject: [PATCH 03/32] Prima implementazione della classe database --- src/.qmake.stash | 23 ++++++++++++++++ src/Memory/Database.cpp | 52 ++++++++++++++++++++++++++++++++++++ src/Memory/Database.h | 19 ++++++++----- src/Memory/MediaContainer.h | 2 +- src/src | Bin 0 -> 42448 bytes src/src.pro | 10 ++++--- 6 files changed, 95 insertions(+), 11 deletions(-) create mode 100644 src/.qmake.stash create mode 100644 src/Memory/Database.cpp create mode 100755 src/src diff --git a/src/.qmake.stash b/src/.qmake.stash new file mode 100644 index 0000000..99e66aa --- /dev/null +++ b/src/.qmake.stash @@ -0,0 +1,23 @@ +QMAKE_CXX.QT_COMPILER_STDCXX = 201703L +QMAKE_CXX.QMAKE_GCC_MAJOR_VERSION = 13 +QMAKE_CXX.QMAKE_GCC_MINOR_VERSION = 3 +QMAKE_CXX.QMAKE_GCC_PATCH_VERSION = 0 +QMAKE_CXX.COMPILER_MACROS = \ + QT_COMPILER_STDCXX \ + QMAKE_GCC_MAJOR_VERSION \ + QMAKE_GCC_MINOR_VERSION \ + QMAKE_GCC_PATCH_VERSION +QMAKE_CXX.INCDIRS = \ + /usr/include/c++/13 \ + /usr/include/x86_64-linux-gnu/c++/13 \ + /usr/include/c++/13/backward \ + /usr/lib/gcc/x86_64-linux-gnu/13/include \ + /usr/local/include \ + /usr/include/x86_64-linux-gnu \ + /usr/include +QMAKE_CXX.LIBDIRS = \ + /usr/lib/gcc/x86_64-linux-gnu/13 \ + /usr/lib/x86_64-linux-gnu \ + /usr/lib \ + /lib/x86_64-linux-gnu \ + /lib diff --git a/src/Memory/Database.cpp b/src/Memory/Database.cpp new file mode 100644 index 0000000..4744e0b --- /dev/null +++ b/src/Memory/Database.cpp @@ -0,0 +1,52 @@ +#include "Database.h" + +namespace memory { +DataBase::~DataBase() { + // può darsi che se ne occupi il distruttore di QFile + // comportamento di default: per ora metto che non vengono salvati i + // cambiamenti + close(false); +} +int DataBase::open(const QString &path) { + // QFile.close() non lancia errori se il file non è stato aperto + // file_.commit(); + file_.setFileName(path); + if (!file_.open(QIODevice::ReadOnly | QIODevice::Text)) { + // TODO(alessandro): possiamo creare una qualche enum per i codici di errore + return 1; + } + return 0; +} +int DataBase::close(bool save_on_exit) { + if (save_on_exit) { + // ritorna false se c'è stato un errore. Possiamo voler cambiare il tipo di + // ritorno del metodo. + file_.commit(); + } else { + // void cancelWriting() + file_.cancelWriting(); + } + return 0; +} + +int DataBase::save() { + // ritorna false in caso di fallimento + if (!file_.commit()) { + // errore in scrittura + return -1; + } + // riapri il file dopo averlo chiuso + // ritorna false in caso di fallimento + if (!file_.open(QIODevice::ReadOnly | QIODevice::Text)) { + return 1; + } + return 0; +} + +// qua possiamo volendo utilizzare riferimenti costanti al posto di puntatori +std::vector DataBase::filterMedia( + const media::Media *media_as_filter) { + return media_container_.filter(media_as_filter); +} + +} // namespace memory diff --git a/src/Memory/Database.h b/src/Memory/Database.h index 3406307..d327857 100644 --- a/src/Memory/Database.h +++ b/src/Memory/Database.h @@ -1,21 +1,26 @@ #ifndef MEMORY_DATABASE_H #define MEMORY_DATABASE_H -#include +#include #include "./MediaContainer.h" namespace memory { -class Database { +class DataBase { private: MediaContainer media_container_; - QFile db_file_; + QSaveFile file_; + // possiamo mettere open, close e save privati e poi usare un tipo di observer + // pattern per chiamare le funzioni. public: - Database() = default; - int open(const std::string &path); - int close(); + DataBase() = default; + ~DataBase(); + int open(const QString &path); + int close(bool save); int save(); - std::vector filterMedia(const media::Media *) const; + // TODO(alessandro): smart pointer + // possiamo cambiarlo a riferimenti costanti + std::vector filterMedia(const media::Media *); }; } // namespace memory #endif diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index cc24df4..fa5e702 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -8,7 +8,7 @@ class MediaContainer { MediaContainer() = default; int addMedia(media::Media *); int removeMedia(media::Media *); - std::vector filter(media::Media *); + std::vector filter(const media::Media *); }; } // namespace memory #endif diff --git a/src/src b/src/src new file mode 100755 index 0000000000000000000000000000000000000000..6084bd1ed587ed399b139104f9d0e36130700e2a GIT binary patch literal 42448 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 O7!l~%i~3-QD*p|m2+v9Y literal 0 HcmV?d00001 diff --git a/src/src.pro b/src/src.pro index 131b69f..fa01e1e 100644 --- a/src/src.pro +++ b/src/src.pro @@ -1,5 +1,5 @@ ###################################################################### -# Automatically generated by qmake (3.1) Mon May 19 10:58:10 2025 +# Automatically generated by qmake (3.1) Mon May 19 16:59:27 2025 ###################################################################### TEMPLATE = app @@ -24,7 +24,10 @@ HEADERS += Media/Album.h \ Media/Movie.h \ Media/Novel.h \ Media/Series.h \ - Memory/MediaContainer.h + Memory/Database.h \ + Memory/Deserializer.h \ + Memory/MediaContainer.h \ + Memory/Serializer.h SOURCES += main.cpp \ Media/Album.cpp \ Media/AudioBook.cpp \ @@ -32,4 +35,5 @@ SOURCES += main.cpp \ Media/Media.cpp \ Media/Movie.cpp \ Media/Novel.cpp \ - Media/Series.cpp + Media/Series.cpp \ + Memory/Database.cpp From ef60e262f3cfa90e7e74b2d5f51149d98db59448 Mon Sep 17 00:00:00 2001 From: b0dyless Date: Mon, 19 May 2025 19:33:16 +0200 Subject: [PATCH 04/32] Prima implementazione della classe database --- src/.qmake.stash | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 src/.qmake.stash diff --git a/src/.qmake.stash b/src/.qmake.stash deleted file mode 100644 index 99e66aa..0000000 --- a/src/.qmake.stash +++ /dev/null @@ -1,23 +0,0 @@ -QMAKE_CXX.QT_COMPILER_STDCXX = 201703L -QMAKE_CXX.QMAKE_GCC_MAJOR_VERSION = 13 -QMAKE_CXX.QMAKE_GCC_MINOR_VERSION = 3 -QMAKE_CXX.QMAKE_GCC_PATCH_VERSION = 0 -QMAKE_CXX.COMPILER_MACROS = \ - QT_COMPILER_STDCXX \ - QMAKE_GCC_MAJOR_VERSION \ - QMAKE_GCC_MINOR_VERSION \ - QMAKE_GCC_PATCH_VERSION -QMAKE_CXX.INCDIRS = \ - /usr/include/c++/13 \ - /usr/include/x86_64-linux-gnu/c++/13 \ - /usr/include/c++/13/backward \ - /usr/lib/gcc/x86_64-linux-gnu/13/include \ - /usr/local/include \ - /usr/include/x86_64-linux-gnu \ - /usr/include -QMAKE_CXX.LIBDIRS = \ - /usr/lib/gcc/x86_64-linux-gnu/13 \ - /usr/lib/x86_64-linux-gnu \ - /usr/lib \ - /lib/x86_64-linux-gnu \ - /lib From 0c72eab7d01cd88b07844c351ae16dcf0c6f98c6 Mon Sep 17 00:00:00 2001 From: b0dyless Date: Mon, 19 May 2025 19:35:40 +0200 Subject: [PATCH 05/32] Aggiornamento .gitignore --- .gitignore | 4 ++++ src/src | Bin 42448 -> 0 bytes 2 files changed, 4 insertions(+) delete mode 100755 src/src diff --git a/.gitignore b/.gitignore index 771d7a4..a44ae58 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +.cache +.qmake.stash +./src + # C++ objects and libs *.slo *.lo diff --git a/src/src b/src/src deleted file mode 100755 index 6084bd1ed587ed399b139104f9d0e36130700e2a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42448 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 O7!l~%i~3-QD*p|m2+v9Y From dc603fc45f36c73c6d7c6fc4e7303933bc296309 Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 11:53:35 +0200 Subject: [PATCH 06/32] Aggiunto metodo Filter per la classe Media --- src/Media/Media.cpp | 56 +++++++++++++++++++++++++++++++++++ src/Media/Media.h | 13 +++++--- src/Memory/MediaContainer.cpp | 30 +++++-------------- src/Memory/MediaContainer.h | 9 ++---- src/StringUtils.h | 20 +++++++++++++ src/main.cpp | 54 ++++++++++++++++++++++++++++++++- 6 files changed, 149 insertions(+), 33 deletions(-) create mode 100644 src/StringUtils.h diff --git a/src/Media/Media.cpp b/src/Media/Media.cpp index 9d732e6..2fcdcae 100644 --- a/src/Media/Media.cpp +++ b/src/Media/Media.cpp @@ -1,4 +1,8 @@ #include "Media.h" +#include +#include +#include +#include namespace media { Media::Media(const std::string &title, int release, const std::string &language, @@ -27,6 +31,58 @@ bool Media::open() { return false; } +std::vector> Media::filter(const std::vector>& input) const { + std::vector> result; + + for (const auto& mediaPtr : input) { + if (!mediaPtr) continue; + + const Media& media = *mediaPtr; + bool match = true; + + // Title (substring, case-insensitive) + if (!getTitle().empty() && !stringContainsIgnoreCase(media.getTitle(), getTitle())) + match = false; + + // Release (confronto stretto) + if (getRelease() != std::numeric_limits::min() && + media.getRelease() != getRelease()) + match = false; + + // Language (substring, case-insensitive) + if (!getLanguage().empty() && media.getLanguage() != getLanguage()) + match = false; + + // Favourite (confronto booleano) + if (isFavourite() && media.isFavourite() != isFavourite()) + match = false; + + // Generi (match parziale case-insensitive su ogni genere richiesto) + if (!getGenres().empty()) { + const auto& mediaGenres = media.getGenres(); + for (const auto& genreFilter : getGenres()) { + bool found = false; + for (const auto& g : mediaGenres) { + if (stringContainsIgnoreCase(g, genreFilter)) { + found = true; + break; + } + } + if (!found) { + match = false; + break; + } + } + } + + if (match) + result.push_back(mediaPtr); + } + + return result; +} + + const std::string &Media::getTitle() const { return title_; } int Media::getRelease() const { return release_; } const std::string &Media::getLanguage() const { return language_; }; diff --git a/src/Media/Media.h b/src/Media/Media.h index d743fe4..dd06409 100644 --- a/src/Media/Media.h +++ b/src/Media/Media.h @@ -3,9 +3,12 @@ #include #include #include +#include +#include #include "IMedia.h" #include "IConstMediaVisitor.h" +#include "StringUtils.h" namespace media { class Media : IMedia{ @@ -19,9 +22,9 @@ class Media : IMedia{ std::string notes_; protected: - Media(const std::string &title, int release, const std::string &language, - bool favourite, const std::vector &genres, - const std::string &img_path, const std::string ¬es); + Media(const std::string &title = "", int release = std::numeric_limits::min(), const std::string &language = "", + bool favourite = false, const std::vector &genres = {}, + const std::string &img_path = "", const std::string ¬es = ""); public: @@ -40,6 +43,8 @@ class Media : IMedia{ const std::vector &getGenres() const; const std::string &getImgPath() const; const std::string &getNotes() const; -}; + + virtual std::vector> filter(const std::vector> &media) const; +}; } // namespace media #endif diff --git a/src/Memory/MediaContainer.cpp b/src/Memory/MediaContainer.cpp index 4fcd3aa..f7ff5df 100644 --- a/src/Memory/MediaContainer.cpp +++ b/src/Memory/MediaContainer.cpp @@ -29,18 +29,6 @@ void MediaContainer::clear() { } } -std::vector> MediaContainer::filterByTitle(const std::string& title) const { - return filter([&](const media::Media& m) { - return m.getTitle() == title; - }); -} - -std::vector> MediaContainer::filterByYear(int year) const { - return filter([&](const media::Media& m) { - return m.getRelease() == year; - }); -} - std::vector> MediaContainer::getAll() const { return data_[static_cast(MediaType::All)]; } @@ -49,16 +37,6 @@ std::vector> MediaContainer::getByType(MediaType t return data_[static_cast(type)]; } -std::vector> MediaContainer::filter(std::function predicate) const { - std::vector> result; - for (const auto& media : data_[static_cast(MediaType::All)]) { - if (predicate(*media)) { - result.push_back(media); - } - } - return result; -} - MediaType MediaContainer::determineType(const std::shared_ptr& media) const { if (std::dynamic_pointer_cast(media)) return MediaType::Series; if (std::dynamic_pointer_cast(media)) return MediaType::Movie; @@ -68,4 +46,12 @@ MediaType MediaContainer::determineType(const std::shared_ptr& med if (std::dynamic_pointer_cast(media)) return MediaType::Album; return MediaType::All; } + +std::vector> MediaContainer::filter(const std::shared_ptr& media) const{ + auto allMedia = getAll(); + return media->filter(allMedia); +} + + + } \ No newline at end of file diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index 72a17c5..e38dea8 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -40,14 +40,11 @@ class MediaContainer { void removeMedia(const std::shared_ptr& media); void clear(); - std::vector> filterByTitle(const std::string& title) const; - std::vector> filterByYear(int year) const; - std::vector> getAll() const; std::vector> getByType(MediaType type) const; - - // Combinazioni di filtri - std::vector> filter(std::function predicate) const; + + //Sezione filtri + std::vector> filter(const std::shared_ptr& media) const; }; } #endif // MEMORY_MEDIACONTAINER_H diff --git a/src/StringUtils.h b/src/StringUtils.h new file mode 100644 index 0000000..5be116a --- /dev/null +++ b/src/StringUtils.h @@ -0,0 +1,20 @@ +#ifndef STRINGUTILS_H +#define STRINGUTILS_H + +#include +#include +#include + +namespace media { +inline std::string toLowerCase(const std::string& str) { + std::string lower = str; + std::transform(lower.begin(), lower.end(), lower.begin(), + [](unsigned char c){ return std::tolower(c); }); + return lower; +} + +inline bool stringContainsIgnoreCase(const std::string& text, const std::string& pattern) { + return toLowerCase(text).find(toLowerCase(pattern)) != std::string::npos; +} +} +#endif // STRINGUTILS_H diff --git a/src/main.cpp b/src/main.cpp index 76e8197..57bbbbb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1 +1,53 @@ -int main() { return 0; } +#include +#include +#include +#include +#include "Media.h" // Include il tuo header + +int main() { + // Crea alcuni media + auto media1 = std::make_shared( + "House of Cards", + 2013, + "English", + std::vector{"Drama", "Politics"}, + true + ); + + auto media2 = std::make_shared( + "The Crown", + 2016, + "English", + std::vector{"History", "Drama"}, + false + ); + + auto media3 = std::make_shared( + "Breaking Bad", + 2008, + "English", + std::vector{"Crime", "Thriller"}, + false + ); + + // Inserisci i media in un vettore + std::vector> inputList = {media1, media2, media3}; + + // Crea un oggetto Media come filtro + auto filterMedia = std::make_shared( + "Ho", + std::numeric_limits::min(), + "dra" + ); + + // Filtra + std::vector> filtered = filterMedia->filter(inputList); + + // Stampa i risultati + std::cout << "Media che passano il filtro:\n"; + for (const auto& m : filtered) { + std::cout << "- " << m->getTitle() << "\n"; + } + + return 0; +} From 6f4fbc38f72e8a725f7ba19161498e7ebc532c34 Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 11:59:49 +0200 Subject: [PATCH 07/32] Aggiunta interfaccia metodi filtra --- src/Memory/MediaContainer.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index e38dea8..62db178 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -45,6 +45,13 @@ class MediaContainer { //Sezione filtri std::vector> filter(const std::shared_ptr& media) const; + std::vector> filter(const std::shared_ptr& novel) const; + std::vector> filter(const std::shared_ptr& album) const; + std::vector> filter(const std::shared_ptr& movie) const; + std::vector> filter(const std::shared_ptr& ebook) const; + std::vector> filter(const std::shared_ptr& audiobook) const; + std::vector> filter(const std::shared_ptr& series) const; + }; } #endif // MEMORY_MEDIACONTAINER_H From 1c9d4f2bee60e23adb7d7dcaf9434dd3ed5e6ffd Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 13:09:41 +0200 Subject: [PATCH 08/32] Tolto il virtual --- src/Media/Media.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Media/Media.h b/src/Media/Media.h index dd06409..9b11618 100644 --- a/src/Media/Media.h +++ b/src/Media/Media.h @@ -44,7 +44,7 @@ class Media : IMedia{ const std::string &getImgPath() const; const std::string &getNotes() const; - virtual std::vector> filter(const std::vector> &media) const; + std::vector> filter(const std::vector> &media) const; }; } // namespace media #endif From c74688d9a395b85b69bdc7b52c1c9758c6c080ed Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 13:32:19 +0200 Subject: [PATCH 09/32] Metodo filter per Novel --- src/Media/Novel.cpp | 42 +++++++++++++++++++++++++++++++++++ src/Media/Novel.h | 3 +++ src/Memory/MediaContainer.cpp | 34 ++++++++++++++++++++++++++-- src/Memory/MediaContainer.h | 13 ++++++----- 4 files changed, 84 insertions(+), 8 deletions(-) diff --git a/src/Media/Novel.cpp b/src/Media/Novel.cpp index 4c827d2..133775e 100644 --- a/src/Media/Novel.cpp +++ b/src/Media/Novel.cpp @@ -33,4 +33,46 @@ void Novel::setPages(unsigned int pages) { pages_ = pages; } void Novel::setSeries(const std::string& series) { series_ = series; } void Novel::setIsbn(const std::string& isbn) { isbn_ = isbn; } + +std::vector> Novel::filter(const std::vector>& input) const { + std::vector> result; + + // Riutilizzo del filtro base di Media + std::vector> baseInput(input.begin(), input.end()); + std::vector> filteredBase = Media::filter(baseInput); + + // Filtro specifico per Novel + for (const auto& mediaPtr : filteredBase) { + auto novelPtr = std::dynamic_pointer_cast(mediaPtr); + if (!novelPtr) continue; + + bool match = true; + + // Autore + if (!author_.empty() && !stringContainsIgnoreCase(novelPtr->getAuthor(), author_)) + match = false; + + // Editore + if (!publisher_.empty() && !stringContainsIgnoreCase(novelPtr->getPublisher(), publisher_)) + match = false; + + // Serie + if (!series_.empty() && !stringContainsIgnoreCase(novelPtr->getSeries(), series_)) + match = false; + + // ISBN + if (!isbn_.empty() && !stringContainsIgnoreCase(novelPtr->getIsbn(), isbn_)) + match = false; + + // Pagine (confronto stretto) + if (pages_ > 0 && novelPtr->getPages() != pages_) + match = false; + + if (match) + result.push_back(novelPtr); + } + + return result; +} + } \ No newline at end of file diff --git a/src/Media/Novel.h b/src/Media/Novel.h index a736000..b61bf12 100644 --- a/src/Media/Novel.h +++ b/src/Media/Novel.h @@ -34,6 +34,9 @@ class Novel : public Media { void setPages(unsigned int pages); void setSeries(const std::string& series); void setIsbn(const std::string& isbn); + + std::vector> filter(const std::vector> &novel) const; }; + } #endif // Novel_H \ No newline at end of file diff --git a/src/Memory/MediaContainer.cpp b/src/Memory/MediaContainer.cpp index f7ff5df..719ff8a 100644 --- a/src/Memory/MediaContainer.cpp +++ b/src/Memory/MediaContainer.cpp @@ -37,6 +37,35 @@ std::vector> MediaContainer::getByType(MediaType t return data_[static_cast(type)]; } +std::vector> MediaContainer::getByTypeAndSubtype(MediaType type) const { + std::vector> result; + + switch (type) { + case MediaType::Novel: + result.insert(result.end(), data_[static_cast(MediaType::Novel)].begin(), data_[static_cast(MediaType::Novel)].end()); + result.insert(result.end(), data_[static_cast(MediaType::EBook)].begin(), data_[static_cast(MediaType::EBook)].end()); + result.insert(result.end(), data_[static_cast(MediaType::AudioBook)].begin(), data_[static_cast(MediaType::AudioBook)].end()); + break; + + case MediaType::Movie: + result.insert(result.end(), data_[static_cast(MediaType::Movie)].begin(), data_[static_cast(MediaType::Movie)].end()); + result.insert(result.end(), data_[static_cast(MediaType::Series)].begin(), data_[static_cast(MediaType::Series)].end()); + break; + + case MediaType::All: + result = data_[0]; // Tutti i media + break; + + default: + // Ritorna il vettore corrispondente solo per quel tipo specifico + result = data_[static_cast(type)]; + break; + } + + return result; +} + + MediaType MediaContainer::determineType(const std::shared_ptr& media) const { if (std::dynamic_pointer_cast(media)) return MediaType::Series; if (std::dynamic_pointer_cast(media)) return MediaType::Movie; @@ -52,6 +81,7 @@ std::vector> MediaContainer::filter(const std::sha return media->filter(allMedia); } - - +std::vector> MediaContainer::filter(const std::shared_ptr& novel) const{ + auto allNovel= getByTypeAndSubtype(MediaType::Novel); + return novel->filter(allNovel); } \ No newline at end of file diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index 62db178..2fdfb6e 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -42,15 +42,16 @@ class MediaContainer { std::vector> getAll() const; std::vector> getByType(MediaType type) const; + std::vector> getByTypeAndSubtype(MediaType type) const; //Sezione filtri std::vector> filter(const std::shared_ptr& media) const; - std::vector> filter(const std::shared_ptr& novel) const; - std::vector> filter(const std::shared_ptr& album) const; - std::vector> filter(const std::shared_ptr& movie) const; - std::vector> filter(const std::shared_ptr& ebook) const; - std::vector> filter(const std::shared_ptr& audiobook) const; - std::vector> filter(const std::shared_ptr& series) const; + std::vector> filter(const std::shared_ptr& novel) const; + std::vector> filter(const std::shared_ptr& album) const; + std::vector> filter(const std::shared_ptr& movie) const; + std::vector> filter(const std::shared_ptr& ebook) const; + std::vector> filter(const std::shared_ptr& audiobook) const; + std::vector> filter(const std::shared_ptr& series) const; }; } From 090cf2484ab4518fb1b5ab449f30a757fa22d2ce Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 13:45:56 +0200 Subject: [PATCH 10/32] Sistemato filtro per Novel --- src/Memory/MediaContainer.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Memory/MediaContainer.cpp b/src/Memory/MediaContainer.cpp index 719ff8a..f5c6f1b 100644 --- a/src/Memory/MediaContainer.cpp +++ b/src/Memory/MediaContainer.cpp @@ -82,6 +82,13 @@ std::vector> MediaContainer::filter(const std::sha } std::vector> MediaContainer::filter(const std::shared_ptr& novel) const{ - auto allNovel= getByTypeAndSubtype(MediaType::Novel); + auto media= getByTypeAndSubtype(MediaType::Novel); + std::vector> allNovel; + for (const auto& mediaPtr : media) { + auto novelPtr = std::dynamic_pointer_cast(mediaPtr); + if (novelPtr) { + allNovel.push_back(novelPtr); + } + } return novel->filter(allNovel); } \ No newline at end of file From 0f5cf1301bde1fa8e095f6109522fe2d901020c7 Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 14:01:51 +0200 Subject: [PATCH 11/32] Aggiunti parametri di default --- src/Media/Album.h | 4 ++-- src/Media/AudioBook.h | 3 ++- src/Media/Ebook.h | 2 +- src/Media/Media.h | 2 +- src/Media/Movie.h | 4 ++-- src/Media/Novel.h | 4 ++-- src/Media/Series.h | 4 ++-- 7 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/Media/Album.h b/src/Media/Album.h index 3839490..c2d5bbc 100644 --- a/src/Media/Album.h +++ b/src/Media/Album.h @@ -13,8 +13,8 @@ class Album : public Media { Album(const std::string &title, int release, const std::string &language, bool favourite, const std::vector &genres, const std::string &img_path, const std::string ¬es, - const std::string &band, const std::vector &band_members, - const std::vector &songs); + const std::string &band = "", const std::vector &band_members = {}, + const std::vector &songs = {}); const std::string &getBand() const; const std::vector &getBandMembers() const; const std::vector &getSongs() const; diff --git a/src/Media/AudioBook.h b/src/Media/AudioBook.h index 4b0bc09..999ab78 100644 --- a/src/Media/AudioBook.h +++ b/src/Media/AudioBook.h @@ -11,11 +11,12 @@ class AudioBook : public Novel { std::string streamingService_; public: + //durata è in minuti e usa il campo dati pagine di Novel AudioBook(const std::string& title, int publicationYear, const std::string& language, bool favorite, const std::vector& genres, const std::string& imagePath, const std::string& notes, const std::string& author, const std::string& publisher, unsigned int duration, const std::string& series, const std::string& isbn, - const std::string& narrator, const std::string& streamingService); + const std::string& narrator = "", const std::string& streamingService = ""); bool operator==(const Media& other) const override; diff --git a/src/Media/Ebook.h b/src/Media/Ebook.h index 7035703..5d5312a 100644 --- a/src/Media/Ebook.h +++ b/src/Media/Ebook.h @@ -15,7 +15,7 @@ class Ebook : public Novel { bool favorite, const std::vector& genres, const std::string& imagePath, const std::string& notes, const std::string& author, const std::string& publisher, unsigned int pages, const std::string& series, const std::string& isbn, - unsigned int fileSizeBytes, bool drm); + unsigned int fileSizeBytes = 0, bool drm = false); bool operator==(const Media& other) const override; diff --git a/src/Media/Media.h b/src/Media/Media.h index 9b11618..2268e81 100644 --- a/src/Media/Media.h +++ b/src/Media/Media.h @@ -22,7 +22,7 @@ class Media : IMedia{ std::string notes_; protected: - Media(const std::string &title = "", int release = std::numeric_limits::min(), const std::string &language = "", + Media(const std::string &title = "", int release = std::numeric_limits::max(), const std::string &language = "", bool favourite = false, const std::vector &genres = {}, const std::string &img_path = "", const std::string ¬es = ""); diff --git a/src/Media/Movie.h b/src/Media/Movie.h index 0c736dc..d630377 100644 --- a/src/Media/Movie.h +++ b/src/Media/Movie.h @@ -17,8 +17,8 @@ class Movie : public Media { Movie(const std::string &title, int release, const std::string &language, bool favourite, const std::vector &genres, const std::string &img_path, const std::string ¬es, - const std::vector &cast, unsigned int length, - const std::string &universe); + const std::vector &cast = {}, unsigned int length = std::numeric_limits::max(), + const std::string &universe = ""); bool operator==(const Media &other) const override; const std::vector &getCast() const; unsigned int getLength() const; diff --git a/src/Media/Novel.h b/src/Media/Novel.h index b61bf12..8fba19d 100644 --- a/src/Media/Novel.h +++ b/src/Media/Novel.h @@ -16,8 +16,8 @@ class Novel : public Media { public: Novel(const std::string& title, int publicationYear, const std::string& language, bool favorite, const std::vector& genres, const std::string& imagePath, const std::string& notes, - const std::string& author, const std::string& publisher, - unsigned int pages, const std::string& series, const std::string& isbn); + const std::string& author = "", const std::string& publisher = "", + unsigned int pages = std::numeric_limits::max(), const std::string& series = "", const std::string& isbn = ""); bool operator==(const Media& other) const override; diff --git a/src/Media/Series.h b/src/Media/Series.h index 036086f..15b1649 100644 --- a/src/Media/Series.h +++ b/src/Media/Series.h @@ -14,8 +14,8 @@ class Series : public Movie { bool favourite, const std::vector &genres, const std::string &img_path, const std::string ¬es, const std::vector &cast, unsigned int length, - const std::string &universe, unsigned int episodes, - unsigned int seasons, bool ended); + const std::string &universe, unsigned int episodes = std::numeric_limits::max(), + unsigned int seasons = std::numeric_limits::max(), bool ended = false); bool operator==(const Media &other) const override; unsigned int getEpisodes() const; unsigned int getSeasons() const; From ac28661b7b8294b4421ee75a4d6c4bcdcc875424 Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 14:26:57 +0200 Subject: [PATCH 12/32] SIstemata la cartella di git --- .gitignore | 3 ++- CMakeLists.txt | 43 ----------------------------------- src/Media/Media.h | 12 +++++----- src/{ => Media}/StringUtils.h | 0 src/main.cpp | 19 ++++++++-------- 5 files changed, 17 insertions(+), 60 deletions(-) delete mode 100644 CMakeLists.txt rename src/{ => Media}/StringUtils.h (100%) diff --git a/.gitignore b/.gitignore index bdb5fa1..33447a5 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ *.so.* *.dll *.dylib -build +Build checks.json # Qt-es @@ -18,6 +18,7 @@ object_script.*.Debug *_plugin_import.cpp /.qmake.cache /.qmake.stash +src/*.qmake.stash *.pro.user *.pro.user.* *.qbs.user diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index e087f6b..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -cmake_minimum_required(VERSION 3.16) - -project(MediaLibraryBuild VERSION 1.0 LANGUAGES CXX) - -# Qt5: automatizza moc, uic, rcc -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# Raccoglie tutti i file .cpp e .h nella cartella src/ -file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS src/*.cpp src/*.h) - -# Crea l'eseguibile principale -add_executable(${PROJECT_NAME} ${SOURCES}) - -target_include_directories(${PROJECT_NAME} PRIVATE src) - -# Trova e linka le librerie Qt necessarie -find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui) - -target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Widgets Qt5::Gui) - -# Imposta la cartella output dell'eseguibile -set_target_properties(${PROJECT_NAME} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} -) - -# Abilita il supporto ai test -enable_testing() - -# Test (facoltativi) -file(GLOB_RECURSE TEST_SOURCES CONFIGURE_DEPENDS src/test*.cpp) - -foreach(test_src ${TEST_SOURCES}) - get_filename_component(test_name ${test_src} NAME_WE) - add_executable(${test_name} ${test_src}) - target_include_directories(${test_name} PRIVATE src) - target_link_libraries(${test_name} PRIVATE Qt5::Core Qt5::Widgets Qt5::Gui) - add_test(NAME ${test_name} COMMAND ${test_name}) -endforeach() diff --git a/src/Media/Media.h b/src/Media/Media.h index 2268e81..0d39960 100644 --- a/src/Media/Media.h +++ b/src/Media/Media.h @@ -21,14 +21,14 @@ class Media : IMedia{ std::string img_path_; std::string notes_; - protected: + + public: + Media(const std::string &title = "", int release = std::numeric_limits::max(), const std::string &language = "", - bool favourite = false, const std::vector &genres = {}, - const std::string &img_path = "", const std::string ¬es = ""); - - public: + bool favourite = false, const std::vector &genres = {}, + const std::string &img_path = "", const std::string ¬es = ""); - virtual bool operator==(const Media &other) const; + virtual bool operator==(const Media &other) const; void accept(IConstMediaVisitor &) const override; bool open() override; diff --git a/src/StringUtils.h b/src/Media/StringUtils.h similarity index 100% rename from src/StringUtils.h rename to src/Media/StringUtils.h diff --git a/src/main.cpp b/src/main.cpp index 57bbbbb..55a15bc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,7 +2,7 @@ #include #include #include -#include "Media.h" // Include il tuo header +#include "Media/Media.h" // Include il tuo header int main() { // Crea alcuni media @@ -10,24 +10,24 @@ int main() { "House of Cards", 2013, "English", - std::vector{"Drama", "Politics"}, - true + true, + std::vector{"Drama", "Politics"} ); auto media2 = std::make_shared( "The Crown", 2016, "English", - std::vector{"History", "Drama"}, - false + false, + std::vector{"History", "Drama"} ); auto media3 = std::make_shared( "Breaking Bad", 2008, "English", - std::vector{"Crime", "Thriller"}, - false + false, + std::vector{"Crime", "Thriller"} ); // Inserisci i media in un vettore @@ -36,14 +36,13 @@ int main() { // Crea un oggetto Media come filtro auto filterMedia = std::make_shared( "Ho", - std::numeric_limits::min(), - "dra" + std::numeric_limits::min() ); // Filtra std::vector> filtered = filterMedia->filter(inputList); - // Stampa i risultati + //Stampa i risultati std::cout << "Media che passano il filtro:\n"; for (const auto& m : filtered) { std::cout << "- " << m->getTitle() << "\n"; From 36fe7d7d0593a5f4322a6f8867058c6dbb7b6418 Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 14:28:29 +0200 Subject: [PATCH 13/32] Modficia .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 33447a5..9b61d93 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ *.dylib Build checks.json +.vscode +build # Qt-es object_script.*.Release From 2886b1353d4cf9a448bb667caf64a8f02471e181 Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 16:06:02 +0200 Subject: [PATCH 14/32] Metodi filter aggiunti ovunque --- src/Media/Album.cpp | 60 +++++++++++++++++++++++ src/Media/Album.h | 3 ++ src/Media/AudioBook.cpp | 29 +++++++++++ src/Media/AudioBook.h | 2 + src/Media/Ebook.cpp | 30 ++++++++++++ src/Media/Ebook.h | 3 ++ src/Media/Movie.cpp | 48 +++++++++++++++++++ src/Media/Movie.h | 2 + src/Media/Novel.cpp | 4 +- src/Media/Novel.h | 2 +- src/Media/Series.cpp | 33 +++++++++++++ src/Media/Series.h | 2 + src/Memory/MediaContainer.cpp | 90 ++++++++++++++++++++++++++++------- src/Memory/MediaContainer.h | 25 +++++----- 14 files changed, 302 insertions(+), 31 deletions(-) diff --git a/src/Media/Album.cpp b/src/Media/Album.cpp index 4f3453c..d19e638 100644 --- a/src/Media/Album.cpp +++ b/src/Media/Album.cpp @@ -26,4 +26,64 @@ bool Album::operator==(const Media &other) const { return false; } +std::vector> Album::filter(const std::vector>& input) const { + std::vector> result; + + // Riutilizzo filtro base di Media + std::vector> baseInput(input.begin(), input.end()); + std::vector> filteredBase = Media::filter(baseInput); + + // Filtro specifico per Album + for (const auto& mediaPtr : filteredBase) { + auto albumPtr = std::dynamic_pointer_cast(mediaPtr); + if (!albumPtr) continue; + + bool match = true; + + // Band + if (!band_.empty() && !stringContainsIgnoreCase(albumPtr->getBand(), band_)) + match = false; + + // Band members (ogni membro richiesto deve matchare almeno uno esistente) + if (!band_members_.empty()) { + for (const auto& memberFilter : band_members_) { + bool found = false; + for (const auto& m : albumPtr->getBandMembers()) { + if (stringContainsIgnoreCase(m, memberFilter)) { + found = true; + break; + } + } + if (!found) { + match = false; + break; + } + } + } + + // Songs (ogni canzone richiesta deve matchare almeno una esistente) + if (!songs_.empty()) { + for (const auto& songFilter : songs_) { + bool found = false; + for (const auto& s : albumPtr->getSongs()) { + if (stringContainsIgnoreCase(s, songFilter)) { + found = true; + break; + } + } + if (!found) { + match = false; + break; + } + } + } + + if (match) + result.push_back(albumPtr); + } + + return result; +} + + } // namespace media diff --git a/src/Media/Album.h b/src/Media/Album.h index c2d5bbc..da0fd7c 100644 --- a/src/Media/Album.h +++ b/src/Media/Album.h @@ -19,6 +19,9 @@ class Album : public Media { const std::vector &getBandMembers() const; const std::vector &getSongs() const; bool operator==(const Media &other) const override; + + std::vector> filter(const std::vector>& input) const; + }; } // namespace media #endif diff --git a/src/Media/AudioBook.cpp b/src/Media/AudioBook.cpp index 4a85455..89f43ca 100644 --- a/src/Media/AudioBook.cpp +++ b/src/Media/AudioBook.cpp @@ -37,4 +37,33 @@ void AudioBook::setStreamingService(const std::string& service) { streamingService_ = service; } +std::vector> AudioBook::filter(const std::vector>& input) const { + std::vector> result; + + // Riutilizza filtro base di Novel (che include filtro di Media) + std::vector> novels(input.begin(), input.end()); + std::vector> filteredNovels = Novel::filter(novels); + + // Filtro specifico AudioBook + for (const auto& novelPtr : filteredNovels) { + auto audiobookPtr = std::dynamic_pointer_cast(novelPtr); + if (!audiobookPtr) continue; + + bool match = true; + + // File size + if (narrator_ != "" && audiobookPtr->getNarrator()!= narrator_) + match = false; + + // DRM + if (streamingService_ != "" && audiobookPtr->getStreamingService() != streamingService_) + match = false; + + if (match) + result.push_back(audiobookPtr); + } + + return result; +} + } \ No newline at end of file diff --git a/src/Media/AudioBook.h b/src/Media/AudioBook.h index 999ab78..b674797 100644 --- a/src/Media/AudioBook.h +++ b/src/Media/AudioBook.h @@ -25,6 +25,8 @@ class AudioBook : public Novel { void setNarrator(const std::string& narrator); void setStreamingService(const std::string& service); + + std::vector> filter(const std::vector>& input) const; }; } diff --git a/src/Media/Ebook.cpp b/src/Media/Ebook.cpp index c12bf2a..60a10c4 100644 --- a/src/Media/Ebook.cpp +++ b/src/Media/Ebook.cpp @@ -36,4 +36,34 @@ void Ebook::setDrm(bool drm) { drm_ = drm; } +std::vector> Ebook::filter(const std::vector>& input) const { + std::vector> result; + + // Riutilizza filtro base di Novel (che include filtro di Media) + std::vector> novels(input.begin(), input.end()); + std::vector> filteredNovels = Novel::filter(novels); + + // Filtro specifico Ebook + for (const auto& novelPtr : filteredNovels) { + auto ebookPtr = std::dynamic_pointer_cast(novelPtr); + if (!ebookPtr) continue; + + bool match = true; + + // File size + if (fileSizeBytes_ > 0 && ebookPtr->getFileSizeBytes() != fileSizeBytes_) + match = false; + + // DRM + if (drm_ && ebookPtr->hasDrm() != drm_) + match = false; + + if (match) + result.push_back(ebookPtr); + } + + return result; +} + + } \ No newline at end of file diff --git a/src/Media/Ebook.h b/src/Media/Ebook.h index 5d5312a..b8282e8 100644 --- a/src/Media/Ebook.h +++ b/src/Media/Ebook.h @@ -24,6 +24,9 @@ class Ebook : public Novel { void setFileSizeBytes(unsigned int size); void setDrm(bool drm); + + std::vector> filter(const std::vector>& input) const; + }; } diff --git a/src/Media/Movie.cpp b/src/Media/Movie.cpp index 026eb63..6d83d6b 100644 --- a/src/Media/Movie.cpp +++ b/src/Media/Movie.cpp @@ -21,4 +21,52 @@ bool Movie::operator==(const Media &other) const { const std::vector &Movie::getCast() const { return cast_; } unsigned int Movie::getLength() const { return length_; } const std::string &Movie::getUniverse() const { return universe_; } + +std::vector> Movie::filter(const std::vector>& input) const { + std::vector> result; + + // Riutilizza filtro base di Media (poiché Movie deriva da Media) + std::vector> baseInput(input.begin(), input.end()); + std::vector> filteredBase = Media::filter(baseInput); + + for (const auto& mediaPtr : filteredBase) { + auto moviePtr = std::dynamic_pointer_cast(mediaPtr); + if (!moviePtr) continue; + + bool match = true; + + // Cast (match parziale, case-insensitive) + if (!cast_.empty()) { + const auto& movieCast = moviePtr->getCast(); + for (const auto& filterCast : cast_) { + bool found = false; + for (const auto& member : movieCast) { + if (stringContainsIgnoreCase(member, filterCast)) { + found = true; + break; + } + } + if (!found) { + match = false; + break; + } + } + } + + // Length (confronto stretto) + if (length_ != std::numeric_limits::max() && moviePtr->getLength() != length_) + match = false; + + // Universe (match parziale, case-insensitive) + if (!universe_.empty() && !stringContainsIgnoreCase(moviePtr->getUniverse(), universe_)) + match = false; + + if (match) + result.push_back(moviePtr); + } + + return result; +} + + } // namespace media diff --git a/src/Media/Movie.h b/src/Media/Movie.h index d630377..c37d134 100644 --- a/src/Media/Movie.h +++ b/src/Media/Movie.h @@ -23,6 +23,8 @@ class Movie : public Media { const std::vector &getCast() const; unsigned int getLength() const; const std::string &getUniverse() const; + + std::vector> filter(const std::vector>& input) const; }; } // namespace media #endif diff --git a/src/Media/Novel.cpp b/src/Media/Novel.cpp index 133775e..88f9195 100644 --- a/src/Media/Novel.cpp +++ b/src/Media/Novel.cpp @@ -34,8 +34,8 @@ void Novel::setSeries(const std::string& series) { series_ = series; } void Novel::setIsbn(const std::string& isbn) { isbn_ = isbn; } -std::vector> Novel::filter(const std::vector>& input) const { - std::vector> result; +std::vector> Novel::filter(const std::vector>& input) const { + std::vector> result; // Riutilizzo del filtro base di Media std::vector> baseInput(input.begin(), input.end()); diff --git a/src/Media/Novel.h b/src/Media/Novel.h index 8fba19d..f5fb608 100644 --- a/src/Media/Novel.h +++ b/src/Media/Novel.h @@ -35,7 +35,7 @@ class Novel : public Media { void setSeries(const std::string& series); void setIsbn(const std::string& isbn); - std::vector> filter(const std::vector> &novel) const; + std::vector> filter(const std::vector> &novel) const; }; } diff --git a/src/Media/Series.cpp b/src/Media/Series.cpp index 4004f93..3dd0a1f 100644 --- a/src/Media/Series.cpp +++ b/src/Media/Series.cpp @@ -24,4 +24,37 @@ bool Series::operator==(const Media &other) const { unsigned int Series::getEpisodes() const { return episodes_; } unsigned int Series::getSeasons() const { return seasons_; } bool Series::isEnded() const { return ended_; } + +std::vector> Series::filter(const std::vector>& input) const { + std::vector> result; + + // Riutilizzo filtro base di Movie (che a sua volta chiama Media::filter) + std::vector> baseInput(input.begin(), input.end()); + std::vector> filteredBase = Movie::filter(baseInput); + + for (const auto& mediaPtr : filteredBase) { + auto seriesPtr = std::dynamic_pointer_cast(mediaPtr); + if (!seriesPtr) continue; + + bool match = true; + + // Episodes (confronto stretto) + if (episodes_ != std::numeric_limits::max() && seriesPtr->getEpisodes() != episodes_) + match = false; + + // Seasons (confronto stretto) + if (seasons_ != std::numeric_limits::max() && seriesPtr->getSeasons() != seasons_) + match = false; + + // Ended (confronto booleano) + if (ended_ && ended_ != seriesPtr->isEnded()) + match = false; + + if (match) + result.push_back(seriesPtr); + } + + return result; +} + } // namespace media diff --git a/src/Media/Series.h b/src/Media/Series.h index 15b1649..a950cb2 100644 --- a/src/Media/Series.h +++ b/src/Media/Series.h @@ -20,6 +20,8 @@ class Series : public Movie { unsigned int getEpisodes() const; unsigned int getSeasons() const; bool isEnded() const; + + std::vector> filter(const std::vector>& input) const; }; } // namespace media #endif diff --git a/src/Memory/MediaContainer.cpp b/src/Memory/MediaContainer.cpp index f5c6f1b..ca51afd 100644 --- a/src/Memory/MediaContainer.cpp +++ b/src/Memory/MediaContainer.cpp @@ -1,4 +1,5 @@ #include "MediaContainer.h" + namespace memory { void MediaContainer::addMedia(const std::shared_ptr& media) { @@ -46,18 +47,14 @@ std::vector> MediaContainer::getByTypeAndSubtype(M result.insert(result.end(), data_[static_cast(MediaType::EBook)].begin(), data_[static_cast(MediaType::EBook)].end()); result.insert(result.end(), data_[static_cast(MediaType::AudioBook)].begin(), data_[static_cast(MediaType::AudioBook)].end()); break; - case MediaType::Movie: result.insert(result.end(), data_[static_cast(MediaType::Movie)].begin(), data_[static_cast(MediaType::Movie)].end()); result.insert(result.end(), data_[static_cast(MediaType::Series)].begin(), data_[static_cast(MediaType::Series)].end()); break; - case MediaType::All: - result = data_[0]; // Tutti i media + result = data_[0]; break; - default: - // Ritorna il vettore corrispondente solo per quel tipo specifico result = data_[static_cast(type)]; break; } @@ -65,7 +62,6 @@ std::vector> MediaContainer::getByTypeAndSubtype(M return result; } - MediaType MediaContainer::determineType(const std::shared_ptr& media) const { if (std::dynamic_pointer_cast(media)) return MediaType::Series; if (std::dynamic_pointer_cast(media)) return MediaType::Movie; @@ -76,19 +72,79 @@ MediaType MediaContainer::determineType(const std::shared_ptr& med return MediaType::All; } -std::vector> MediaContainer::filter(const std::shared_ptr& media) const{ +std::vector> MediaContainer::filter(const std::shared_ptr& media) const { + if (auto m = std::dynamic_pointer_cast(media)) return filters(m); + if (auto m = std::dynamic_pointer_cast(media)) return filters(m); + if (auto m = std::dynamic_pointer_cast(media)) return filters(m); + if (auto m = std::dynamic_pointer_cast(media)) return filters(m); + if (auto m = std::dynamic_pointer_cast(media)) return filters(m); + if (auto m = std::dynamic_pointer_cast(media)) return filters(m); + return filters(media); +} + +std::vector> MediaContainer::filters(const std::shared_ptr& media) const { auto allMedia = getAll(); return media->filter(allMedia); } -std::vector> MediaContainer::filter(const std::shared_ptr& novel) const{ - auto media= getByTypeAndSubtype(MediaType::Novel); +std::vector> MediaContainer::filters(const std::shared_ptr& novel) const { + auto media = getByTypeAndSubtype(MediaType::Novel); std::vector> allNovel; - for (const auto& mediaPtr : media) { - auto novelPtr = std::dynamic_pointer_cast(mediaPtr); - if (novelPtr) { - allNovel.push_back(novelPtr); - } - } - return novel->filter(allNovel); -} \ No newline at end of file + for (const auto& m : media) + if (auto ptr = std::dynamic_pointer_cast(m)) allNovel.push_back(ptr); + std::vector> result; + for (const auto& m : novel->filter(allNovel)) result.push_back(m); + return result; +} + +std::vector> MediaContainer::filters(const std::shared_ptr& album) const { + auto media = getByType(MediaType::Album); + std::vector> allAlbum; + for (const auto& m : media) + if (auto ptr = std::dynamic_pointer_cast(m)) allAlbum.push_back(ptr); + std::vector> result; + for (const auto& m : album->filter(allAlbum)) result.push_back(m); + return result; +} + +std::vector> MediaContainer::filters(const std::shared_ptr& movie) const { + auto media = getByTypeAndSubtype(MediaType::Movie); + std::vector> allMovie; + for (const auto& m : media) + if (auto ptr = std::dynamic_pointer_cast(m)) allMovie.push_back(ptr); + std::vector> result; + for (const auto& m : movie->filter(allMovie)) result.push_back(m); + return result; +} + +std::vector> MediaContainer::filters(const std::shared_ptr& ebook) const { + auto media = getByType(MediaType::EBook); + std::vector> allEbook; + for (const auto& m : media) + if (auto ptr = std::dynamic_pointer_cast(m)) allEbook.push_back(ptr); + std::vector> result; + for (const auto& m : ebook->filter(allEbook)) result.push_back(m); + return result; +} + +std::vector> MediaContainer::filters(const std::shared_ptr& audiobook) const { + auto media = getByType(MediaType::AudioBook); + std::vector> allAudio; + for (const auto& m : media) + if (auto ptr = std::dynamic_pointer_cast(m)) allAudio.push_back(ptr); + std::vector> result; + for (const auto& m : audiobook->filter(allAudio)) result.push_back(m); + return result; +} + +std::vector> MediaContainer::filters(const std::shared_ptr& series) const { + auto media = getByType(MediaType::Series); + std::vector> allSeries; + for (const auto& m : media) + if (auto ptr = std::dynamic_pointer_cast(m)) allSeries.push_back(ptr); + std::vector> result; + for (const auto& m : series->filter(allSeries)) result.push_back(m); + return result; +} + +} // namespace memory diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index 2fdfb6e..19c018e 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -6,7 +6,6 @@ #include #include #include -#include #include "Media.h" #include "Novel.h" @@ -16,7 +15,7 @@ #include "AudioBook.h" #include "Series.h" -namespace memory{ +namespace memory { enum class MediaType { All = 0, @@ -26,7 +25,7 @@ enum class MediaType { EBook, AudioBook, Series, - Count // serve per la dimensione dell’array + Count }; class MediaContainer { @@ -35,6 +34,14 @@ class MediaContainer { MediaType determineType(const std::shared_ptr& media) const; + std::vector> filters(const std::shared_ptr& media) const; + std::vector> filters(const std::shared_ptr& novel) const; + std::vector> filters(const std::shared_ptr& album) const; + std::vector> filters(const std::shared_ptr& movie) const; + std::vector> filters(const std::shared_ptr& ebook) const; + std::vector> filters(const std::shared_ptr& audiobook) const; + std::vector> filters(const std::shared_ptr& series) const; + public: void addMedia(const std::shared_ptr& media); void removeMedia(const std::shared_ptr& media); @@ -44,15 +51,11 @@ class MediaContainer { std::vector> getByType(MediaType type) const; std::vector> getByTypeAndSubtype(MediaType type) const; - //Sezione filtri + // Filtri std::vector> filter(const std::shared_ptr& media) const; - std::vector> filter(const std::shared_ptr& novel) const; - std::vector> filter(const std::shared_ptr& album) const; - std::vector> filter(const std::shared_ptr& movie) const; - std::vector> filter(const std::shared_ptr& ebook) const; - std::vector> filter(const std::shared_ptr& audiobook) const; - std::vector> filter(const std::shared_ptr& series) const; }; -} + +} // namespace memory + #endif // MEMORY_MEDIACONTAINER_H From 60a6ad8d2f4f570ca113123c074c90b5f411a82d Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 16:09:36 +0200 Subject: [PATCH 15/32] Modificato nome programma .pro --- src/src.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src.pro b/src/src.pro index 131b69f..a6c6f88 100644 --- a/src/src.pro +++ b/src/src.pro @@ -3,7 +3,7 @@ ###################################################################### TEMPLATE = app -TARGET = src +TARGET = MediaLibrary INCLUDEPATH += . QT += widgets From a6dab30562e32f20c8040468ee59b073b81607c0 Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 16:09:59 +0200 Subject: [PATCH 16/32] Modificato nome .pro --- src/{src.pro => MediaLibrary.pro} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{src.pro => MediaLibrary.pro} (100%) diff --git a/src/src.pro b/src/MediaLibrary.pro similarity index 100% rename from src/src.pro rename to src/MediaLibrary.pro From 15db58b665a3a7ab592637732895462555ddc1c0 Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 16:12:29 +0200 Subject: [PATCH 17/32] Sistemati nomi file --- src/Memory/Deserializer.h | 7 ++++--- src/Memory/Serializer.h | 7 +++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Memory/Deserializer.h b/src/Memory/Deserializer.h index c86b172..12e1040 100644 --- a/src/Memory/Deserializer.h +++ b/src/Memory/Deserializer.h @@ -1,16 +1,17 @@ #ifndef MEMORY_DESERIALIZER_H #define MEMORY_DESERIALIZER_H #include + #include "../Media/Media.h" namespace memory { class Deserializer { private: - static int vecToJSON(const std::vector &, QFile &); - static int vecToXML(const std::vector &, QFile &); + static std::vector& XMLtoVec(const QFile &); + static std::vector& JSONtoVec(const QFile &); public: - static int deserialize(const std::vector &, QFile &); + static std::vector& deserialize(const QFile &); }; } // namespace memory #endif diff --git a/src/Memory/Serializer.h b/src/Memory/Serializer.h index f34aad0..79b0546 100644 --- a/src/Memory/Serializer.h +++ b/src/Memory/Serializer.h @@ -1,17 +1,16 @@ #ifndef MEMORY_SERIALIZER_H #define MEMORY_SERIALIZER_H #include - #include "../Media/Media.h" namespace memory { class Serializer { private: - static std::vector& XMLtoVec(const QFile &); - static std::vector& JSONtoVec(const QFile &); + static int vecToJSON(const std::vector &, QFile &); + static int vecToXML(const std::vector &, QFile &); public: - static std::vector& serialize(const QFile &); + static int Serialize(const std::vector &, QFile &); }; } // namespace memory #endif From 91e29abf535d34eb2ef7e8e897d3186436c9a274 Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 16:15:27 +0200 Subject: [PATCH 18/32] Sistemati #ifndef --- src/Media/AudioBook.h | 6 +++--- src/Media/Ebook.h | 6 +++--- src/Media/IMedia.h | 7 ++----- src/Media/Novel.h | 6 +++--- src/Media/Series.h | 4 ++-- src/Media/StringUtils.h | 6 +++--- 6 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/Media/AudioBook.h b/src/Media/AudioBook.h index b674797..38d77fa 100644 --- a/src/Media/AudioBook.h +++ b/src/Media/AudioBook.h @@ -1,5 +1,5 @@ -#ifndef AudioBook_H -#define AudioBook_H +#ifndef MEDIA_AUDIOBOOK_H +#define MEDIA_AUDIOBOOK_H #include "Novel.h" @@ -31,4 +31,4 @@ class AudioBook : public Novel { } -#endif // AudioBook_H \ No newline at end of file +#endif // MEDIA_AUDIOBOOK_H \ No newline at end of file diff --git a/src/Media/Ebook.h b/src/Media/Ebook.h index b8282e8..d2ba138 100644 --- a/src/Media/Ebook.h +++ b/src/Media/Ebook.h @@ -1,5 +1,5 @@ -#ifndef EBOOK_H -#define EBOOK_H +#ifndef MEDIA_EBOOK_H +#define MEDIA_EBOOK_H #include "Novel.h" @@ -31,4 +31,4 @@ class Ebook : public Novel { } -#endif // EBOOK_H \ No newline at end of file +#endif // MEDIA_EBOOK_H \ No newline at end of file diff --git a/src/Media/IMedia.h b/src/Media/IMedia.h index 4f603b7..d2ffa8b 100644 --- a/src/Media/IMedia.h +++ b/src/Media/IMedia.h @@ -1,12 +1,10 @@ -#ifndef IMedia_H -#define IMedia_H +#ifndef MEDIA_IMedia_H +#define MEDIA_IMedia_H #include "IConstMediaVisitor.h" - namespace media { - class IMedia { virtual void accept(IConstMediaVisitor &) const = 0; virtual bool open() = 0; @@ -14,5 +12,4 @@ class IMedia { } - #endif \ No newline at end of file diff --git a/src/Media/Novel.h b/src/Media/Novel.h index f5fb608..64f91c9 100644 --- a/src/Media/Novel.h +++ b/src/Media/Novel.h @@ -1,5 +1,5 @@ -#ifndef Romanzo_H -#define Romanzo_H +#ifndef MEDIA_ROMANZO_H +#define MEDIA_ROMANZO_H #include "Media.h" @@ -39,4 +39,4 @@ class Novel : public Media { }; } -#endif // Novel_H \ No newline at end of file +#endif // MEDIA_ROMANZO_H \ No newline at end of file diff --git a/src/Media/Series.h b/src/Media/Series.h index a950cb2..42118bc 100644 --- a/src/Media/Series.h +++ b/src/Media/Series.h @@ -23,5 +23,5 @@ class Series : public Movie { std::vector> filter(const std::vector>& input) const; }; -} // namespace media -#endif +} +#endif // MEDIA_SERIES_H diff --git a/src/Media/StringUtils.h b/src/Media/StringUtils.h index 5be116a..9d52635 100644 --- a/src/Media/StringUtils.h +++ b/src/Media/StringUtils.h @@ -1,5 +1,5 @@ -#ifndef STRINGUTILS_H -#define STRINGUTILS_H +#ifndef MEDIA_STRINGUTILS_H +#define MEDIA_STRINGUTILS_H #include #include @@ -17,4 +17,4 @@ inline bool stringContainsIgnoreCase(const std::string& text, const std::string& return toLowerCase(text).find(toLowerCase(pattern)) != std::string::npos; } } -#endif // STRINGUTILS_H +#endif // MEDIA_STRINGUTILS_H From b7a36248c18d0b0aff5510ba61e3811a5f930228 Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 16:33:33 +0200 Subject: [PATCH 19/32] Sistemato interfacce e parte di Filtri --- src/Memory/Deserializer.h | 6 +++--- src/Memory/MediaContainer.cpp | 4 ++++ src/Memory/MediaContainer.h | 3 +++ src/Memory/Serializer.h | 8 ++++---- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/Memory/Deserializer.h b/src/Memory/Deserializer.h index 12e1040..d44d427 100644 --- a/src/Memory/Deserializer.h +++ b/src/Memory/Deserializer.h @@ -7,11 +7,11 @@ namespace memory { class Deserializer { private: - static std::vector& XMLtoVec(const QFile &); - static std::vector& JSONtoVec(const QFile &); + static std::vector>& XMLtoVec(const QFile &); + static std::vector>& JSONtoVec(const QFile &); public: - static std::vector& deserialize(const QFile &); + static std::vector>& deserialize(const QFile &); }; } // namespace memory #endif diff --git a/src/Memory/MediaContainer.cpp b/src/Memory/MediaContainer.cpp index ca51afd..c92553c 100644 --- a/src/Memory/MediaContainer.cpp +++ b/src/Memory/MediaContainer.cpp @@ -147,4 +147,8 @@ std::vector> MediaContainer::filters(const std::sh return result; } +int MediaContainer::serialize(QSaveFile& file) const { + return Serializer::Serialize(getAll(), file); +} + } // namespace memory diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index 19c018e..38ea5ec 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "Media.h" #include "Novel.h" @@ -14,6 +15,7 @@ #include "Ebook.h" #include "AudioBook.h" #include "Series.h" +#include "Serializer.h" namespace memory { @@ -54,6 +56,7 @@ class MediaContainer { // Filtri std::vector> filter(const std::shared_ptr& media) const; + int serialize(QSaveFile& file) const; }; } // namespace memory diff --git a/src/Memory/Serializer.h b/src/Memory/Serializer.h index 79b0546..34b5fa9 100644 --- a/src/Memory/Serializer.h +++ b/src/Memory/Serializer.h @@ -1,16 +1,16 @@ #ifndef MEMORY_SERIALIZER_H #define MEMORY_SERIALIZER_H -#include +#include #include "../Media/Media.h" namespace memory { class Serializer { private: - static int vecToJSON(const std::vector &, QFile &); - static int vecToXML(const std::vector &, QFile &); + static int vecToJSON(const std::vector> &, QSaveFile &); + static int vecToXML(const std::vector> &, QSaveFile &); public: - static int Serialize(const std::vector &, QFile &); + static int Serialize(const std::vector> &, QSaveFile &); }; } // namespace memory #endif From 548e73cb16acad53839ef8e16355380091fbaa7e Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 17:07:32 +0200 Subject: [PATCH 20/32] Sistemato riferimenti --- src/Memory/MediaContainer.cpp | 24 +++++++++++++----------- src/Memory/MediaContainer.h | 12 ++++++------ 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/Memory/MediaContainer.cpp b/src/Memory/MediaContainer.cpp index c92553c..7d9c177 100644 --- a/src/Memory/MediaContainer.cpp +++ b/src/Memory/MediaContainer.cpp @@ -30,15 +30,15 @@ void MediaContainer::clear() { } } -std::vector> MediaContainer::getAll() const { +const std::vector>& MediaContainer::getAll() const { return data_[static_cast(MediaType::All)]; } -std::vector> MediaContainer::getByType(MediaType type) const { +const std::vector>& MediaContainer::getByType(MediaType type) const { return data_[static_cast(type)]; } -std::vector> MediaContainer::getByTypeAndSubtype(MediaType type) const { +const std::vector>& MediaContainer::getByTypeAndSubtype(MediaType type) const { std::vector> result; switch (type) { @@ -72,14 +72,16 @@ MediaType MediaContainer::determineType(const std::shared_ptr& med return MediaType::All; } -std::vector> MediaContainer::filter(const std::shared_ptr& media) const { - if (auto m = std::dynamic_pointer_cast(media)) return filters(m); - if (auto m = std::dynamic_pointer_cast(media)) return filters(m); - if (auto m = std::dynamic_pointer_cast(media)) return filters(m); - if (auto m = std::dynamic_pointer_cast(media)) return filters(m); - if (auto m = std::dynamic_pointer_cast(media)) return filters(m); - if (auto m = std::dynamic_pointer_cast(media)) return filters(m); - return filters(media); +std::vector> MediaContainer::filter(const media::Media& media) const { + std::shared_ptr mediaPtr = std::make_shared(media); + + if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); + if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); + if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); + if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); + if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); + if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); + return filters(mediaPtr); } std::vector> MediaContainer::filters(const std::shared_ptr& media) const { diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index 38ea5ec..c4d5938 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -44,17 +44,17 @@ class MediaContainer { std::vector> filters(const std::shared_ptr& audiobook) const; std::vector> filters(const std::shared_ptr& series) const; + const std::vector>& getAll() const; + const std::vector>& getByType(MediaType type) const; + const std::vector>& getByTypeAndSubtype(MediaType type) const; + public: void addMedia(const std::shared_ptr& media); void removeMedia(const std::shared_ptr& media); void clear(); - - std::vector> getAll() const; - std::vector> getByType(MediaType type) const; - std::vector> getByTypeAndSubtype(MediaType type) const; - + // Filtri - std::vector> filter(const std::shared_ptr& media) const; + std::vector> filter(const media::Media& media) const; int serialize(QSaveFile& file) const; }; From f9a5cf83acfca263ee08a0922b7d619be2e1712b Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 21:06:13 +0200 Subject: [PATCH 21/32] Modificato sostanzialmente tutti i metodi filter --- src/Media/Album.cpp | 76 +++++++-------- src/Media/Album.h | 3 +- src/Media/AudioBook.cpp | 34 +++---- src/Media/AudioBook.h | 2 +- src/Media/Ebook.cpp | 46 ++++----- src/Media/Ebook.h | 2 +- src/Media/Media.cpp | 78 +++++++--------- src/Media/Media.h | 2 +- src/Media/Movie.cpp | 65 ++++++------- src/Media/Movie.h | 3 +- src/Media/Novel.cpp | 70 ++++++-------- src/Media/Novel.h | 2 +- src/Media/Series.cpp | 41 ++++---- src/Media/Series.h | 2 +- src/Memory/MediaContainer.cpp | 171 ++++++++++++---------------------- src/Memory/MediaContainer.h | 50 ++++------ src/Memory/Serializer.h | 6 +- 17 files changed, 258 insertions(+), 395 deletions(-) diff --git a/src/Media/Album.cpp b/src/Media/Album.cpp index d19e638..ec5da60 100644 --- a/src/Media/Album.cpp +++ b/src/Media/Album.cpp @@ -26,64 +26,52 @@ bool Album::operator==(const Media &other) const { return false; } -std::vector> Album::filter(const std::vector>& input) const { - std::vector> result; - +bool Album::filter(const Media& album) const { // Riutilizzo filtro base di Media - std::vector> baseInput(input.begin(), input.end()); - std::vector> filteredBase = Media::filter(baseInput); - - // Filtro specifico per Album - for (const auto& mediaPtr : filteredBase) { - auto albumPtr = std::dynamic_pointer_cast(mediaPtr); - if (!albumPtr) continue; + if (!Media::filter(album)) + return false; - bool match = true; + // Cast to Album to access Album-specific members + const Album* albumPtr = dynamic_cast(&album); + if (!albumPtr) + return false; - // Band - if (!band_.empty() && !stringContainsIgnoreCase(albumPtr->getBand(), band_)) - match = false; + // Band + if (!band_.empty() && !stringContainsIgnoreCase(albumPtr->getBand(), band_)) + return false; - // Band members (ogni membro richiesto deve matchare almeno uno esistente) - if (!band_members_.empty()) { - for (const auto& memberFilter : band_members_) { - bool found = false; - for (const auto& m : albumPtr->getBandMembers()) { - if (stringContainsIgnoreCase(m, memberFilter)) { - found = true; - break; - } - } - if (!found) { - match = false; + // Band members (ogni membro richiesto deve matchare almeno uno esistente) + if (!band_members_.empty()) { + for (const auto& memberFilter : band_members_) { + bool found = false; + for (const auto& m : albumPtr->getBandMembers()) { + if (stringContainsIgnoreCase(m, memberFilter)) { + found = true; break; } } + if (!found) { + return false; + } } + } - // Songs (ogni canzone richiesta deve matchare almeno una esistente) - if (!songs_.empty()) { - for (const auto& songFilter : songs_) { - bool found = false; - for (const auto& s : albumPtr->getSongs()) { - if (stringContainsIgnoreCase(s, songFilter)) { - found = true; - break; - } - } - if (!found) { - match = false; + // Songs (ogni canzone richiesta deve matchare almeno una esistente) + if (!songs_.empty()) { + for (const auto& songFilter : songs_) { + bool found = false; + for (const auto& s : albumPtr->getSongs()) { + if (stringContainsIgnoreCase(s, songFilter)) { + found = true; break; } } + if (!found) { + return false; + } } - - if (match) - result.push_back(albumPtr); } - - return result; + return true; } - } // namespace media diff --git a/src/Media/Album.h b/src/Media/Album.h index da0fd7c..ca30cd3 100644 --- a/src/Media/Album.h +++ b/src/Media/Album.h @@ -20,8 +20,9 @@ class Album : public Media { const std::vector &getSongs() const; bool operator==(const Media &other) const override; - std::vector> filter(const std::vector>& input) const; + bool filter(const Media& album) const override; }; } // namespace media + #endif diff --git a/src/Media/AudioBook.cpp b/src/Media/AudioBook.cpp index 89f43ca..51ba54f 100644 --- a/src/Media/AudioBook.cpp +++ b/src/Media/AudioBook.cpp @@ -37,33 +37,21 @@ void AudioBook::setStreamingService(const std::string& service) { streamingService_ = service; } -std::vector> AudioBook::filter(const std::vector>& input) const { - std::vector> result; - - // Riutilizza filtro base di Novel (che include filtro di Media) - std::vector> novels(input.begin(), input.end()); - std::vector> filteredNovels = Novel::filter(novels); +bool AudioBook::filter(const Media& input) const { + if (!Novel::filter(input)) + return false; + const AudioBook* audiobookPtr = dynamic_cast(&input); + if (!audiobookPtr) + return false; // Protegge da cast fallito // Filtro specifico AudioBook - for (const auto& novelPtr : filteredNovels) { - auto audiobookPtr = std::dynamic_pointer_cast(novelPtr); - if (!audiobookPtr) continue; - - bool match = true; - - // File size - if (narrator_ != "" && audiobookPtr->getNarrator()!= narrator_) - match = false; + if (!narrator_.empty() && !stringContainsIgnoreCase(audiobookPtr->getNarrator(), narrator_)) + return false; - // DRM - if (streamingService_ != "" && audiobookPtr->getStreamingService() != streamingService_) - match = false; - - if (match) - result.push_back(audiobookPtr); - } + if (!streamingService_.empty() && !stringContainsIgnoreCase(audiobookPtr->getStreamingService(), streamingService_)) + return false; - return result; + return true; } } \ No newline at end of file diff --git a/src/Media/AudioBook.h b/src/Media/AudioBook.h index 38d77fa..e383e0c 100644 --- a/src/Media/AudioBook.h +++ b/src/Media/AudioBook.h @@ -26,7 +26,7 @@ class AudioBook : public Novel { void setNarrator(const std::string& narrator); void setStreamingService(const std::string& service); - std::vector> filter(const std::vector>& input) const; + bool filter(const Media& audiobook) const override; }; } diff --git a/src/Media/Ebook.cpp b/src/Media/Ebook.cpp index 60a10c4..d75ddc5 100644 --- a/src/Media/Ebook.cpp +++ b/src/Media/Ebook.cpp @@ -36,34 +36,24 @@ void Ebook::setDrm(bool drm) { drm_ = drm; } -std::vector> Ebook::filter(const std::vector>& input) const { - std::vector> result; - - // Riutilizza filtro base di Novel (che include filtro di Media) - std::vector> novels(input.begin(), input.end()); - std::vector> filteredNovels = Novel::filter(novels); - - // Filtro specifico Ebook - for (const auto& novelPtr : filteredNovels) { - auto ebookPtr = std::dynamic_pointer_cast(novelPtr); - if (!ebookPtr) continue; - - bool match = true; - - // File size - if (fileSizeBytes_ > 0 && ebookPtr->getFileSizeBytes() != fileSizeBytes_) - match = false; - - // DRM - if (drm_ && ebookPtr->hasDrm() != drm_) - match = false; - - if (match) - result.push_back(ebookPtr); - } - - return result; +bool Ebook::filter(const Media& input) const { + // Riutilizzo filtro base di Novel + if (!Novel::filter(input)) + return false; + // Cast to Ebook to access Ebook-specific members + const Ebook* ebookPtr = dynamic_cast(&input); + if (!ebookPtr) + return false; + + // File size filter + if (fileSizeBytes_ > 0 && ebookPtr->getFileSizeBytes() != fileSizeBytes_) + return false; + + // DRM filter + if (drm_ && ebookPtr->hasDrm() != drm_) + return false; + + return true; } - } \ No newline at end of file diff --git a/src/Media/Ebook.h b/src/Media/Ebook.h index d2ba138..1c8dc01 100644 --- a/src/Media/Ebook.h +++ b/src/Media/Ebook.h @@ -25,7 +25,7 @@ class Ebook : public Novel { void setFileSizeBytes(unsigned int size); void setDrm(bool drm); - std::vector> filter(const std::vector>& input) const; + bool filter(const Media& ebook) const override; }; diff --git a/src/Media/Media.cpp b/src/Media/Media.cpp index 2fcdcae..45e0f5d 100644 --- a/src/Media/Media.cpp +++ b/src/Media/Media.cpp @@ -31,55 +31,45 @@ bool Media::open() { return false; } -std::vector> Media::filter(const std::vector>& input) const { - std::vector> result; - - for (const auto& mediaPtr : input) { - if (!mediaPtr) continue; - - const Media& media = *mediaPtr; - bool match = true; - - // Title (substring, case-insensitive) - if (!getTitle().empty() && !stringContainsIgnoreCase(media.getTitle(), getTitle())) - match = false; - - // Release (confronto stretto) - if (getRelease() != std::numeric_limits::min() && - media.getRelease() != getRelease()) - match = false; - - // Language (substring, case-insensitive) - if (!getLanguage().empty() && media.getLanguage() != getLanguage()) - match = false; - - // Favourite (confronto booleano) - if (isFavourite() && media.isFavourite() != isFavourite()) - match = false; - - // Generi (match parziale case-insensitive su ogni genere richiesto) - if (!getGenres().empty()) { - const auto& mediaGenres = media.getGenres(); - for (const auto& genreFilter : getGenres()) { - bool found = false; - for (const auto& g : mediaGenres) { - if (stringContainsIgnoreCase(g, genreFilter)) { - found = true; - break; - } - } - if (!found) { - match = false; +bool Media::filter(const Media& media) const { + bool match = true; + + // Title (substring, case-insensitive) + if (!getTitle().empty() && !stringContainsIgnoreCase(media.getTitle(), getTitle())) + match = false; + + // Release (confronto stretto) + if (getRelease() != std::numeric_limits::min() && + media.getRelease() != getRelease()) + match = false; + + // Language (substring, case-insensitive) + if (!getLanguage().empty() && media.getLanguage() != getLanguage()) + match = false; + + // Favourite (confronto booleano) + if (isFavourite() && media.isFavourite() != isFavourite()) + match = false; + + // Generi (match parziale case-insensitive su ogni genere richiesto) + if (!getGenres().empty()) { + const auto& mediaGenres = media.getGenres(); + for (const auto& genreFilter : getGenres()) { + bool found = false; + for (const auto& g : mediaGenres) { + if (stringContainsIgnoreCase(g, genreFilter)) { + found = true; break; } } + if (!found) { + match = false; + break; + } } + } - if (match) - result.push_back(mediaPtr); - } - - return result; + return match; } diff --git a/src/Media/Media.h b/src/Media/Media.h index 0d39960..621efd5 100644 --- a/src/Media/Media.h +++ b/src/Media/Media.h @@ -44,7 +44,7 @@ class Media : IMedia{ const std::string &getImgPath() const; const std::string &getNotes() const; - std::vector> filter(const std::vector> &media) const; + virtual bool filter(const Media &media) const; }; } // namespace media #endif diff --git a/src/Media/Movie.cpp b/src/Media/Movie.cpp index 6d83d6b..82f541b 100644 --- a/src/Media/Movie.cpp +++ b/src/Media/Movie.cpp @@ -22,51 +22,44 @@ const std::vector &Movie::getCast() const { return cast_; } unsigned int Movie::getLength() const { return length_; } const std::string &Movie::getUniverse() const { return universe_; } -std::vector> Movie::filter(const std::vector>& input) const { - std::vector> result; +bool Movie::filter(const Media& movie) const { - // Riutilizza filtro base di Media (poiché Movie deriva da Media) - std::vector> baseInput(input.begin(), input.end()); - std::vector> filteredBase = Media::filter(baseInput); + if (!Media::filter(movie)) + return false; - for (const auto& mediaPtr : filteredBase) { - auto moviePtr = std::dynamic_pointer_cast(mediaPtr); - if (!moviePtr) continue; - - bool match = true; - - // Cast (match parziale, case-insensitive) - if (!cast_.empty()) { - const auto& movieCast = moviePtr->getCast(); - for (const auto& filterCast : cast_) { - bool found = false; - for (const auto& member : movieCast) { - if (stringContainsIgnoreCase(member, filterCast)) { - found = true; - break; - } - } - if (!found) { - match = false; + // Cast (match parziale, case-insensitive) + const Movie* moviePtr = dynamic_cast(&movie); + if (!moviePtr) { + return false; + } + if (!cast_.empty()) { + const auto& movieCast = moviePtr->getCast(); + for (const auto& filterCast : cast_) { + bool found = false; + for (const auto& member : movieCast) { + if (stringContainsIgnoreCase(member, filterCast)) { + found = true; break; } } + if (!found) { + return false; + } } - - // Length (confronto stretto) - if (length_ != std::numeric_limits::max() && moviePtr->getLength() != length_) - match = false; - - // Universe (match parziale, case-insensitive) - if (!universe_.empty() && !stringContainsIgnoreCase(moviePtr->getUniverse(), universe_)) - match = false; - - if (match) - result.push_back(moviePtr); } - return result; + // Length (confronto stretto) + if (length_ != std::numeric_limits::max() && moviePtr->getLength() != length_) + return false; + + // Universe (match parziale, case-insensitive) + if (!universe_.empty() && !stringContainsIgnoreCase(moviePtr->getUniverse(), universe_)) + return false; + + return true; } } // namespace media + + diff --git a/src/Media/Movie.h b/src/Media/Movie.h index c37d134..2d96c7a 100644 --- a/src/Media/Movie.h +++ b/src/Media/Movie.h @@ -24,7 +24,8 @@ class Movie : public Media { unsigned int getLength() const; const std::string &getUniverse() const; - std::vector> filter(const std::vector>& input) const; + bool filter(const Media& movie) const override; }; } // namespace media #endif + diff --git a/src/Media/Novel.cpp b/src/Media/Novel.cpp index 88f9195..3368c4e 100644 --- a/src/Media/Novel.cpp +++ b/src/Media/Novel.cpp @@ -34,45 +34,37 @@ void Novel::setSeries(const std::string& series) { series_ = series; } void Novel::setIsbn(const std::string& isbn) { isbn_ = isbn; } -std::vector> Novel::filter(const std::vector>& input) const { - std::vector> result; - - // Riutilizzo del filtro base di Media - std::vector> baseInput(input.begin(), input.end()); - std::vector> filteredBase = Media::filter(baseInput); - - // Filtro specifico per Novel - for (const auto& mediaPtr : filteredBase) { - auto novelPtr = std::dynamic_pointer_cast(mediaPtr); - if (!novelPtr) continue; - - bool match = true; - - // Autore - if (!author_.empty() && !stringContainsIgnoreCase(novelPtr->getAuthor(), author_)) - match = false; - - // Editore - if (!publisher_.empty() && !stringContainsIgnoreCase(novelPtr->getPublisher(), publisher_)) - match = false; - - // Serie - if (!series_.empty() && !stringContainsIgnoreCase(novelPtr->getSeries(), series_)) - match = false; - - // ISBN - if (!isbn_.empty() && !stringContainsIgnoreCase(novelPtr->getIsbn(), isbn_)) - match = false; - - // Pagine (confronto stretto) - if (pages_ > 0 && novelPtr->getPages() != pages_) - match = false; - - if (match) - result.push_back(novelPtr); - } - - return result; +bool Novel::filter(const Media& input) const { + // Riutilizzo filtro base di Media + if (!Media::filter(input)) + return false; + // Cast to Novel to access Novel-specific members + const Novel* novelPtr = dynamic_cast(&input); + if (!novelPtr) + return false; + + // Match fields + // Autore + if (!author_.empty() && !stringContainsIgnoreCase(novelPtr->getAuthor(), author_)) + return false; + + // Editore + if (!publisher_.empty() && !stringContainsIgnoreCase(novelPtr->getPublisher(), publisher_)) + return false; + + // Serie + if (!series_.empty() && !stringContainsIgnoreCase(novelPtr->getSeries(), series_)) + return false; + + // ISBN + if (!isbn_.empty() && !stringContainsIgnoreCase(novelPtr->getIsbn(), isbn_)) + return false; + + // Pagine (confronto stretto) + if (pages_ != std::numeric_limits::max() && novelPtr->getPages() != pages_) + return false; + + return true; } } \ No newline at end of file diff --git a/src/Media/Novel.h b/src/Media/Novel.h index 64f91c9..edab6b5 100644 --- a/src/Media/Novel.h +++ b/src/Media/Novel.h @@ -35,7 +35,7 @@ class Novel : public Media { void setSeries(const std::string& series); void setIsbn(const std::string& isbn); - std::vector> filter(const std::vector> &novel) const; + bool filter(const Media &novel) const override; }; } diff --git a/src/Media/Series.cpp b/src/Media/Series.cpp index 3dd0a1f..d9cdcac 100644 --- a/src/Media/Series.cpp +++ b/src/Media/Series.cpp @@ -25,36 +25,27 @@ unsigned int Series::getEpisodes() const { return episodes_; } unsigned int Series::getSeasons() const { return seasons_; } bool Series::isEnded() const { return ended_; } -std::vector> Series::filter(const std::vector>& input) const { - std::vector> result; +bool Series::filter(const Media& input) const { + if (!Movie::filter(input)) + return false; - // Riutilizzo filtro base di Movie (che a sua volta chiama Media::filter) - std::vector> baseInput(input.begin(), input.end()); - std::vector> filteredBase = Movie::filter(baseInput); + const Series* seriesPtr = dynamic_cast(&input); + if (!seriesPtr) + return false; // Protegge da cast fallito - for (const auto& mediaPtr : filteredBase) { - auto seriesPtr = std::dynamic_pointer_cast(mediaPtr); - if (!seriesPtr) continue; + // Episodes (confronto stretto) + if (episodes_ != std::numeric_limits::max() && seriesPtr->getEpisodes() != episodes_) + return false; - bool match = true; + // Seasons (confronto stretto) + if (seasons_ != std::numeric_limits::max() && seriesPtr->getSeasons() != seasons_) + return false; - // Episodes (confronto stretto) - if (episodes_ != std::numeric_limits::max() && seriesPtr->getEpisodes() != episodes_) - match = false; + // Ended (confronto booleano) + if (ended_ && ended_ != seriesPtr->isEnded()) + return false; - // Seasons (confronto stretto) - if (seasons_ != std::numeric_limits::max() && seriesPtr->getSeasons() != seasons_) - match = false; - - // Ended (confronto booleano) - if (ended_ && ended_ != seriesPtr->isEnded()) - match = false; - - if (match) - result.push_back(seriesPtr); - } - - return result; + return true; } } // namespace media diff --git a/src/Media/Series.h b/src/Media/Series.h index 42118bc..fedbda6 100644 --- a/src/Media/Series.h +++ b/src/Media/Series.h @@ -21,7 +21,7 @@ class Series : public Movie { unsigned int getSeasons() const; bool isEnded() const; - std::vector> filter(const std::vector>& input) const; + bool filter(const Media& input) const override; }; } #endif // MEDIA_SERIES_H diff --git a/src/Memory/MediaContainer.cpp b/src/Memory/MediaContainer.cpp index 7d9c177..151f720 100644 --- a/src/Memory/MediaContainer.cpp +++ b/src/Memory/MediaContainer.cpp @@ -1,25 +1,41 @@ #include "MediaContainer.h" +#include +#include namespace memory { -void MediaContainer::addMedia(const std::shared_ptr& media) { - if (!media) return; +void MediaContainer::addMedia(const media::Media& media) { + data_[INDEX_ALL].push_back(media); - data_[static_cast(MediaType::All)].push_back(media); - - MediaType type = determineType(media); - if (type != MediaType::All) { - data_[static_cast(type)].push_back(media); + if (detectIndex(media) == INDEX_ALL) { + return; // Media already exists in the container + } else { + data_[detectIndex(media)].push_back(media); } } -void MediaContainer::removeMedia(const std::shared_ptr& media) { - if (!media) return; +int MediaContainer::detectIndex(const media::Media& media) const { + if (dynamic_cast(&media)) { + return INDEX_SERIES; + } else if (dynamic_cast(&media)) { + return INDEX_AUDIOBOOK; + } else if (dynamic_cast(&media)) { + return INDEX_EBOOK; + } else if (dynamic_cast(&media)) { + return INDEX_MOVIE; + } else if (dynamic_cast(&media)) { + return INDEX_ALBUM; + } else if (dynamic_cast(&media)) { + return INDEX_NOVEL; + } + return INDEX_ALL; // Default case +} +void MediaContainer::removeMedia(const media::Media& media) { for (auto& vec : data_) { vec.erase(std::remove_if(vec.begin(), vec.end(), - [&](const std::shared_ptr& m) { - return typeid(*m) == typeid(*media) && *m == *media; + [&](const media::Media& m) { + return typeid(m) == typeid(media) && m == media; }), vec.end()); } } @@ -30,127 +46,54 @@ void MediaContainer::clear() { } } -const std::vector>& MediaContainer::getAll() const { - return data_[static_cast(MediaType::All)]; +const std::vector& MediaContainer::getAll() const { + return data_[INDEX_ALL]; +} + +const std::vector& MediaContainer::getByIndex(int idx) const { + return data_[idx]; } -const std::vector>& MediaContainer::getByType(MediaType type) const { - return data_[static_cast(type)]; +const std::vector& MediaContainer::getByIndex(int idx) const { + return data_[idx]; } -const std::vector>& MediaContainer::getByTypeAndSubtype(MediaType type) const { - std::vector> result; +std::vector MediaContainer::getByGroupIndex(int idx) const { + std::vector result; - switch (type) { - case MediaType::Novel: - result.insert(result.end(), data_[static_cast(MediaType::Novel)].begin(), data_[static_cast(MediaType::Novel)].end()); - result.insert(result.end(), data_[static_cast(MediaType::EBook)].begin(), data_[static_cast(MediaType::EBook)].end()); - result.insert(result.end(), data_[static_cast(MediaType::AudioBook)].begin(), data_[static_cast(MediaType::AudioBook)].end()); + switch (idx) { + case INDEX_NOVEL: + result.insert(result.end(), data_[INDEX_NOVEL].begin(), data_[INDEX_NOVEL].end()); + result.insert(result.end(), data_[INDEX_EBOOK].begin(), data_[INDEX_EBOOK].end()); + result.insert(result.end(), data_[INDEX_AUDIOBOOK].begin(), data_[INDEX_AUDIOBOOK].end()); break; - case MediaType::Movie: - result.insert(result.end(), data_[static_cast(MediaType::Movie)].begin(), data_[static_cast(MediaType::Movie)].end()); - result.insert(result.end(), data_[static_cast(MediaType::Series)].begin(), data_[static_cast(MediaType::Series)].end()); + case INDEX_MOVIE: + result.insert(result.end(), data_[INDEX_MOVIE].begin(), data_[INDEX_MOVIE].end()); + result.insert(result.end(), data_[INDEX_SERIES].begin(), data_[INDEX_SERIES].end()); break; - case MediaType::All: - result = data_[0]; + case INDEX_ALL: + result.insert(result.end(), data_[INDEX_ALL].begin(), data_[INDEX_ALL].end()); break; default: - result = data_[static_cast(type)]; + result.insert(result.end(), data_[idx].begin(), data_[idx].end()); break; } return result; } -MediaType MediaContainer::determineType(const std::shared_ptr& media) const { - if (std::dynamic_pointer_cast(media)) return MediaType::Series; - if (std::dynamic_pointer_cast(media)) return MediaType::Movie; - if (std::dynamic_pointer_cast(media)) return MediaType::AudioBook; - if (std::dynamic_pointer_cast(media)) return MediaType::EBook; - if (std::dynamic_pointer_cast(media)) return MediaType::Novel; - if (std::dynamic_pointer_cast(media)) return MediaType::Album; - return MediaType::All; -} - -std::vector> MediaContainer::filter(const media::Media& media) const { - std::shared_ptr mediaPtr = std::make_shared(media); - - if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); - if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); - if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); - if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); - if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); - if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); - return filters(mediaPtr); -} - -std::vector> MediaContainer::filters(const std::shared_ptr& media) const { - auto allMedia = getAll(); - return media->filter(allMedia); -} - -std::vector> MediaContainer::filters(const std::shared_ptr& novel) const { - auto media = getByTypeAndSubtype(MediaType::Novel); - std::vector> allNovel; - for (const auto& m : media) - if (auto ptr = std::dynamic_pointer_cast(m)) allNovel.push_back(ptr); - std::vector> result; - for (const auto& m : novel->filter(allNovel)) result.push_back(m); - return result; -} - -std::vector> MediaContainer::filters(const std::shared_ptr& album) const { - auto media = getByType(MediaType::Album); - std::vector> allAlbum; - for (const auto& m : media) - if (auto ptr = std::dynamic_pointer_cast(m)) allAlbum.push_back(ptr); - std::vector> result; - for (const auto& m : album->filter(allAlbum)) result.push_back(m); - return result; -} - -std::vector> MediaContainer::filters(const std::shared_ptr& movie) const { - auto media = getByTypeAndSubtype(MediaType::Movie); - std::vector> allMovie; - for (const auto& m : media) - if (auto ptr = std::dynamic_pointer_cast(m)) allMovie.push_back(ptr); - std::vector> result; - for (const auto& m : movie->filter(allMovie)) result.push_back(m); - return result; -} - -std::vector> MediaContainer::filters(const std::shared_ptr& ebook) const { - auto media = getByType(MediaType::EBook); - std::vector> allEbook; - for (const auto& m : media) - if (auto ptr = std::dynamic_pointer_cast(m)) allEbook.push_back(ptr); - std::vector> result; - for (const auto& m : ebook->filter(allEbook)) result.push_back(m); - return result; -} - -std::vector> MediaContainer::filters(const std::shared_ptr& audiobook) const { - auto media = getByType(MediaType::AudioBook); - std::vector> allAudio; - for (const auto& m : media) - if (auto ptr = std::dynamic_pointer_cast(m)) allAudio.push_back(ptr); - std::vector> result; - for (const auto& m : audiobook->filter(allAudio)) result.push_back(m); - return result; -} - -std::vector> MediaContainer::filters(const std::shared_ptr& series) const { - auto media = getByType(MediaType::Series); - std::vector> allSeries; - for (const auto& m : media) - if (auto ptr = std::dynamic_pointer_cast(m)) allSeries.push_back(ptr); - std::vector> result; - for (const auto& m : series->filter(allSeries)) result.push_back(m); - return result; +std::vector MediaContainer::filter(const media::Media& media) const { + std::vector results; + for (const media::Media* m : getByGroupIndex(detectIndex(media))) { + if (media.filter(*m)) { + results.push_back(m); + } + } + return results; } int MediaContainer::serialize(QSaveFile& file) const { - return Serializer::Serialize(getAll(), file); + return Serializer::Serialize(data_[INDEX_ALL], file); } } // namespace memory diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index c4d5938..e4fa4bf 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -3,9 +3,6 @@ #include #include -#include -#include -#include #include #include "Media.h" @@ -19,42 +16,31 @@ namespace memory { -enum class MediaType { - All = 0, - Novel, - Album, - Movie, - EBook, - AudioBook, - Series, - Count -}; - class MediaContainer { private: - std::array>, static_cast(MediaType::Count)> data_; - - MediaType determineType(const std::shared_ptr& media) const; + static constexpr int INDEX_ALL = 0; + static constexpr int INDEX_NOVEL = 1; + static constexpr int INDEX_ALBUM = 2; + static constexpr int INDEX_MOVIE = 3; + static constexpr int INDEX_EBOOK = 4; + static constexpr int INDEX_AUDIOBOOK = 5; + static constexpr int INDEX_SERIES = 6; + static constexpr int TYPE_COUNT = 7; - std::vector> filters(const std::shared_ptr& media) const; - std::vector> filters(const std::shared_ptr& novel) const; - std::vector> filters(const std::shared_ptr& album) const; - std::vector> filters(const std::shared_ptr& movie) const; - std::vector> filters(const std::shared_ptr& ebook) const; - std::vector> filters(const std::shared_ptr& audiobook) const; - std::vector> filters(const std::shared_ptr& series) const; + std::array, TYPE_COUNT> data_; - const std::vector>& getAll() const; - const std::vector>& getByType(MediaType type) const; - const std::vector>& getByTypeAndSubtype(MediaType type) const; + int detectIndex(const media::Media& media) const; + std::vector MediaContainer::getByGroupIndex(int idx) const; public: - void addMedia(const std::shared_ptr& media); - void removeMedia(const std::shared_ptr& media); + void addMedia(const media::Media& media); + void removeMedia(const media::Media& media); void clear(); - - // Filtri - std::vector> filter(const media::Media& media) const; + + std::vector filter(const media::Media& media) const; + + const std::vector& getAll() const; + const std::vector& getByIndex(int idx) const; int serialize(QSaveFile& file) const; }; diff --git a/src/Memory/Serializer.h b/src/Memory/Serializer.h index 34b5fa9..47a9274 100644 --- a/src/Memory/Serializer.h +++ b/src/Memory/Serializer.h @@ -6,11 +6,11 @@ namespace memory { class Serializer { private: - static int vecToJSON(const std::vector> &, QSaveFile &); - static int vecToXML(const std::vector> &, QSaveFile &); + static int vecToJSON(const media::Media &, QSaveFile &); + static int vecToXML(const media::Media&, QSaveFile &); public: - static int Serialize(const std::vector> &, QSaveFile &); + static int Serialize(const std::vector&, QSaveFile &); }; } // namespace memory #endif From 4078e0fbb27833a1ba2d88d9e1fd4a9b41fd68c1 Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 21:26:08 +0200 Subject: [PATCH 22/32] Sistemato gli include giusti --- src/Memory/MediaContainer.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index e4fa4bf..df52479 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -5,13 +5,13 @@ #include #include -#include "Media.h" -#include "Novel.h" -#include "Album.h" -#include "Movie.h" -#include "Ebook.h" -#include "AudioBook.h" -#include "Series.h" +#include "../Media/Media.h" +#include "../Media/Novel.h" +#include "../Media/Album.h" +#include "../Media/Movie.h" +#include "../Media/Ebook.h" +#include "../Media/AudioBook.h" +#include "../Media/Series.h" #include "Serializer.h" namespace memory { From 869ef101ad6bacd871a289b424d537dbd1d3a643 Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 21:35:59 +0200 Subject: [PATCH 23/32] Corretto cosa filter Media --- src/Media/Media.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/Media/Media.cpp b/src/Media/Media.cpp index 45e0f5d..33d81f8 100644 --- a/src/Media/Media.cpp +++ b/src/Media/Media.cpp @@ -32,24 +32,22 @@ bool Media::open() { } bool Media::filter(const Media& media) const { - bool match = true; - - // Title (substring, case-insensitive) + // Title (substring, case-insensitive) if (!getTitle().empty() && !stringContainsIgnoreCase(media.getTitle(), getTitle())) - match = false; + return false; // Release (confronto stretto) if (getRelease() != std::numeric_limits::min() && media.getRelease() != getRelease()) - match = false; + return false; // Language (substring, case-insensitive) if (!getLanguage().empty() && media.getLanguage() != getLanguage()) - match = false; + return false; // Favourite (confronto booleano) if (isFavourite() && media.isFavourite() != isFavourite()) - match = false; + return false; // Generi (match parziale case-insensitive su ogni genere richiesto) if (!getGenres().empty()) { @@ -63,13 +61,12 @@ bool Media::filter(const Media& media) const { } } if (!found) { - match = false; - break; + return false; } } } - return match; + return true; } From 79bc9d17e69880a7c724af5d3973f16c42eca49f Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 22:03:41 +0200 Subject: [PATCH 24/32] Solo per compilazione aggiunto {} metodi static --- src/Memory/Database.cpp | 52 ----------------------------------- src/Memory/Database.h | 26 ------------------ src/Memory/Deserializer.h | 6 ++-- src/Memory/MediaContainer.cpp | 25 +++++++++-------- src/Memory/MediaContainer.h | 2 +- src/Memory/Serializer.h | 7 +++-- src/main.cpp | 43 ----------------------------- 7 files changed, 22 insertions(+), 139 deletions(-) delete mode 100644 src/Memory/Database.cpp delete mode 100644 src/Memory/Database.h diff --git a/src/Memory/Database.cpp b/src/Memory/Database.cpp deleted file mode 100644 index 4744e0b..0000000 --- a/src/Memory/Database.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "Database.h" - -namespace memory { -DataBase::~DataBase() { - // può darsi che se ne occupi il distruttore di QFile - // comportamento di default: per ora metto che non vengono salvati i - // cambiamenti - close(false); -} -int DataBase::open(const QString &path) { - // QFile.close() non lancia errori se il file non è stato aperto - // file_.commit(); - file_.setFileName(path); - if (!file_.open(QIODevice::ReadOnly | QIODevice::Text)) { - // TODO(alessandro): possiamo creare una qualche enum per i codici di errore - return 1; - } - return 0; -} -int DataBase::close(bool save_on_exit) { - if (save_on_exit) { - // ritorna false se c'è stato un errore. Possiamo voler cambiare il tipo di - // ritorno del metodo. - file_.commit(); - } else { - // void cancelWriting() - file_.cancelWriting(); - } - return 0; -} - -int DataBase::save() { - // ritorna false in caso di fallimento - if (!file_.commit()) { - // errore in scrittura - return -1; - } - // riapri il file dopo averlo chiuso - // ritorna false in caso di fallimento - if (!file_.open(QIODevice::ReadOnly | QIODevice::Text)) { - return 1; - } - return 0; -} - -// qua possiamo volendo utilizzare riferimenti costanti al posto di puntatori -std::vector DataBase::filterMedia( - const media::Media *media_as_filter) { - return media_container_.filter(media_as_filter); -} - -} // namespace memory diff --git a/src/Memory/Database.h b/src/Memory/Database.h deleted file mode 100644 index d327857..0000000 --- a/src/Memory/Database.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef MEMORY_DATABASE_H -#define MEMORY_DATABASE_H -#include - -#include "./MediaContainer.h" - -namespace memory { -class DataBase { - private: - MediaContainer media_container_; - QSaveFile file_; - - // possiamo mettere open, close e save privati e poi usare un tipo di observer - // pattern per chiamare le funzioni. - public: - DataBase() = default; - ~DataBase(); - int open(const QString &path); - int close(bool save); - int save(); - // TODO(alessandro): smart pointer - // possiamo cambiarlo a riferimenti costanti - std::vector filterMedia(const media::Media *); -}; -} // namespace memory -#endif diff --git a/src/Memory/Deserializer.h b/src/Memory/Deserializer.h index d44d427..fb074c9 100644 --- a/src/Memory/Deserializer.h +++ b/src/Memory/Deserializer.h @@ -7,11 +7,11 @@ namespace memory { class Deserializer { private: - static std::vector>& XMLtoVec(const QFile &); - static std::vector>& JSONtoVec(const QFile &); + static std::vector>& XMLtoVec(const QFile &){} + static std::vector>& JSONtoVec(const QFile &){} public: - static std::vector>& deserialize(const QFile &); + static std::vector>& deserialize(const QFile &){} }; } // namespace memory #endif diff --git a/src/Memory/MediaContainer.cpp b/src/Memory/MediaContainer.cpp index 151f720..16d046b 100644 --- a/src/Memory/MediaContainer.cpp +++ b/src/Memory/MediaContainer.cpp @@ -54,34 +54,37 @@ const std::vector& MediaContainer::getByIndex(int idx) const { return data_[idx]; } -const std::vector& MediaContainer::getByIndex(int idx) const { - return data_[idx]; -} - std::vector MediaContainer::getByGroupIndex(int idx) const { std::vector result; + auto appendGroup = [&](int groupIndex) { + for (const auto& media : data_[groupIndex]) { + result.push_back(&media); + } + }; + switch (idx) { case INDEX_NOVEL: - result.insert(result.end(), data_[INDEX_NOVEL].begin(), data_[INDEX_NOVEL].end()); - result.insert(result.end(), data_[INDEX_EBOOK].begin(), data_[INDEX_EBOOK].end()); - result.insert(result.end(), data_[INDEX_AUDIOBOOK].begin(), data_[INDEX_AUDIOBOOK].end()); + appendGroup(INDEX_NOVEL); + appendGroup(INDEX_EBOOK); + appendGroup(INDEX_AUDIOBOOK); break; case INDEX_MOVIE: - result.insert(result.end(), data_[INDEX_MOVIE].begin(), data_[INDEX_MOVIE].end()); - result.insert(result.end(), data_[INDEX_SERIES].begin(), data_[INDEX_SERIES].end()); + appendGroup(INDEX_MOVIE); + appendGroup(INDEX_SERIES); break; case INDEX_ALL: - result.insert(result.end(), data_[INDEX_ALL].begin(), data_[INDEX_ALL].end()); + appendGroup(INDEX_ALL); break; default: - result.insert(result.end(), data_[idx].begin(), data_[idx].end()); + appendGroup(idx); break; } return result; } + std::vector MediaContainer::filter(const media::Media& media) const { std::vector results; for (const media::Media* m : getByGroupIndex(detectIndex(media))) { diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index df52479..fa86bf0 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -30,7 +30,7 @@ class MediaContainer { std::array, TYPE_COUNT> data_; int detectIndex(const media::Media& media) const; - std::vector MediaContainer::getByGroupIndex(int idx) const; + std::vector getByGroupIndex(int idx) const; public: void addMedia(const media::Media& media); diff --git a/src/Memory/Serializer.h b/src/Memory/Serializer.h index 47a9274..40ea2bd 100644 --- a/src/Memory/Serializer.h +++ b/src/Memory/Serializer.h @@ -5,12 +5,13 @@ namespace memory { class Serializer { + private: - static int vecToJSON(const media::Media &, QSaveFile &); - static int vecToXML(const media::Media&, QSaveFile &); + static int vecToJSON(const media::Media &, QSaveFile &){} + static int vecToXML(const media::Media&, QSaveFile &){} public: - static int Serialize(const std::vector&, QSaveFile &); + static int Serialize(const std::vector&, QSaveFile &){} }; } // namespace memory #endif diff --git a/src/main.cpp b/src/main.cpp index 55a15bc..b8ec46d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,48 +5,5 @@ #include "Media/Media.h" // Include il tuo header int main() { - // Crea alcuni media - auto media1 = std::make_shared( - "House of Cards", - 2013, - "English", - true, - std::vector{"Drama", "Politics"} - ); - - auto media2 = std::make_shared( - "The Crown", - 2016, - "English", - false, - std::vector{"History", "Drama"} - ); - - auto media3 = std::make_shared( - "Breaking Bad", - 2008, - "English", - false, - std::vector{"Crime", "Thriller"} - ); - - // Inserisci i media in un vettore - std::vector> inputList = {media1, media2, media3}; - - // Crea un oggetto Media come filtro - auto filterMedia = std::make_shared( - "Ho", - std::numeric_limits::min() - ); - - // Filtra - std::vector> filtered = filterMedia->filter(inputList); - - //Stampa i risultati - std::cout << "Media che passano il filtro:\n"; - for (const auto& m : filtered) { - std::cout << "- " << m->getTitle() << "\n"; - } - return 0; } From a55646421d3905506efc57237c29632512a02c0a Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 22:35:28 +0200 Subject: [PATCH 25/32] Modfichi con indici --- src/Memory/MediaContainer.cpp | 4 ++++ src/Memory/MediaContainer.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Memory/MediaContainer.cpp b/src/Memory/MediaContainer.cpp index 16d046b..461c66f 100644 --- a/src/Memory/MediaContainer.cpp +++ b/src/Memory/MediaContainer.cpp @@ -54,6 +54,10 @@ const std::vector& MediaContainer::getByIndex(int idx) const { return data_[idx]; } +const std::vector& MediaContainer::getByIndex(int idx) const { + return data_[idx]; +} + std::vector MediaContainer::getByGroupIndex(int idx) const { std::vector result; diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index fa86bf0..df52479 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -30,7 +30,7 @@ class MediaContainer { std::array, TYPE_COUNT> data_; int detectIndex(const media::Media& media) const; - std::vector getByGroupIndex(int idx) const; + std::vector MediaContainer::getByGroupIndex(int idx) const; public: void addMedia(const media::Media& media); From b58dc987428545c49c0dca34d71ec9e2a5c9e17b Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 22:41:27 +0200 Subject: [PATCH 26/32] Aggiunta classe Enum --- src/Memory/MediaContainer.cpp | 99 ++++++++++++++++++----------------- src/Memory/MediaContainer.h | 29 +++++----- src/main.cpp | 1 + 3 files changed, 68 insertions(+), 61 deletions(-) diff --git a/src/Memory/MediaContainer.cpp b/src/Memory/MediaContainer.cpp index 461c66f..f00fddf 100644 --- a/src/Memory/MediaContainer.cpp +++ b/src/Memory/MediaContainer.cpp @@ -4,31 +4,35 @@ namespace memory { -void MediaContainer::addMedia(const media::Media& media) { - data_[INDEX_ALL].push_back(media); +void MediaContainer::addMedia(const media::Media& media) { + data_[static_cast(Type::All)].push_back(media); - if (detectIndex(media) == INDEX_ALL) { - return; // Media already exists in the container - } else { - data_[detectIndex(media)].push_back(media); + Type t = detectType(media); + if (t != Type::All) { + data_[static_cast(t)].push_back(media); } } -int MediaContainer::detectIndex(const media::Media& media) const { +MediaContainer::Type MediaContainer::detectType(const media::Media& media) const { if (dynamic_cast(&media)) { - return INDEX_SERIES; - } else if (dynamic_cast(&media)) { - return INDEX_AUDIOBOOK; - } else if (dynamic_cast(&media)) { - return INDEX_EBOOK; - } else if (dynamic_cast(&media)) { - return INDEX_MOVIE; - } else if (dynamic_cast(&media)) { - return INDEX_ALBUM; - } else if (dynamic_cast(&media)) { - return INDEX_NOVEL; + return Type::Series; } - return INDEX_ALL; // Default case + if (dynamic_cast(&media)) { + return Type::AudioBook; + } + if (dynamic_cast(&media)) { + return Type::Ebook; + } + if (dynamic_cast(&media)) { + return Type::Movie; + } + if (dynamic_cast(&media)) { + return Type::Album; + } + if (dynamic_cast(&media)) { + return Type::Novel; + } + return Type::All; } void MediaContainer::removeMedia(const media::Media& media) { @@ -47,51 +51,50 @@ void MediaContainer::clear() { } const std::vector& MediaContainer::getAll() const { - return data_[INDEX_ALL]; -} - -const std::vector& MediaContainer::getByIndex(int idx) const { - return data_[idx]; + return data_[static_cast(Type::All)]; } -const std::vector& MediaContainer::getByIndex(int idx) const { - return data_[idx]; +const std::vector& MediaContainer::getByType(Type type) const { + return data_[static_cast(type)]; } -std::vector MediaContainer::getByGroupIndex(int idx) const { +std::vector MediaContainer::getByGroup(Type type) const { std::vector result; - auto appendGroup = [&](int groupIndex) { - for (const auto& media : data_[groupIndex]) { + auto appendGroup = [&](Type t) { + for (const auto& media : data_[static_cast(t)]) { result.push_back(&media); } }; - switch (idx) { - case INDEX_NOVEL: - appendGroup(INDEX_NOVEL); - appendGroup(INDEX_EBOOK); - appendGroup(INDEX_AUDIOBOOK); - break; - case INDEX_MOVIE: - appendGroup(INDEX_MOVIE); - appendGroup(INDEX_SERIES); - break; - case INDEX_ALL: - appendGroup(INDEX_ALL); - break; - default: - appendGroup(idx); - break; + switch (type) { + case Type::Novel: + appendGroup(Type::Novel); + appendGroup(Type::Ebook); + appendGroup(Type::AudioBook); + break; + + case Type::Movie: + appendGroup(Type::Movie); + appendGroup(Type::Series); + break; + + case Type::All: + appendGroup(Type::All); + break; + + default: + appendGroup(type); + break; } return result; } - std::vector MediaContainer::filter(const media::Media& media) const { std::vector results; - for (const media::Media* m : getByGroupIndex(detectIndex(media))) { + Type t = detectType(media); + for (const media::Media* m : getByGroup(t)) { if (media.filter(*m)) { results.push_back(m); } @@ -100,7 +103,7 @@ std::vector MediaContainer::filter(const media::Media& medi } int MediaContainer::serialize(QSaveFile& file) const { - return Serializer::Serialize(data_[INDEX_ALL], file); + return Serializer::Serialize(data_[static_cast(Type::All)], file); } } // namespace memory diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index df52479..badbe26 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -17,20 +17,23 @@ namespace memory { class MediaContainer { -private: - static constexpr int INDEX_ALL = 0; - static constexpr int INDEX_NOVEL = 1; - static constexpr int INDEX_ALBUM = 2; - static constexpr int INDEX_MOVIE = 3; - static constexpr int INDEX_EBOOK = 4; - static constexpr int INDEX_AUDIOBOOK = 5; - static constexpr int INDEX_SERIES = 6; - static constexpr int TYPE_COUNT = 7; +public: + enum class Type { + All = 0, + Novel, + Album, + Movie, + Ebook, + AudioBook, + Series, + TypeCount + }; - std::array, TYPE_COUNT> data_; +private: + std::array, static_cast(Type::TypeCount)> data_; - int detectIndex(const media::Media& media) const; - std::vector MediaContainer::getByGroupIndex(int idx) const; + Type detectType(const media::Media& media) const; + std::vector getByGroup(Type type) const; public: void addMedia(const media::Media& media); @@ -40,7 +43,7 @@ class MediaContainer { std::vector filter(const media::Media& media) const; const std::vector& getAll() const; - const std::vector& getByIndex(int idx) const; + const std::vector& getByType(Type type) const; int serialize(QSaveFile& file) const; }; diff --git a/src/main.cpp b/src/main.cpp index b8ec46d..4a96007 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,5 +5,6 @@ #include "Media/Media.h" // Include il tuo header int main() { + std::cout << "Aggiornato" << std::endl; return 0; } From c6ecd1a729ab9762e4bb028bc2a35374699daf05 Mon Sep 17 00:00:00 2001 From: Steva0 Date: Tue, 20 May 2025 22:45:21 +0200 Subject: [PATCH 27/32] Aggiornato in privato --- src/Memory/MediaContainer.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index badbe26..620176a 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -17,7 +17,7 @@ namespace memory { class MediaContainer { -public: +private: enum class Type { All = 0, Novel, @@ -29,12 +29,12 @@ class MediaContainer { TypeCount }; -private: std::array, static_cast(Type::TypeCount)> data_; Type detectType(const media::Media& media) const; + const std::vector& getByType(Type type) const; std::vector getByGroup(Type type) const; - + public: void addMedia(const media::Media& media); void removeMedia(const media::Media& media); @@ -43,7 +43,6 @@ class MediaContainer { std::vector filter(const media::Media& media) const; const std::vector& getAll() const; - const std::vector& getByType(Type type) const; int serialize(QSaveFile& file) const; }; From ccaac5e89d98698eca081bf8b815fefc03338f48 Mon Sep 17 00:00:00 2001 From: b0dyless Date: Wed, 21 May 2025 11:44:05 +0200 Subject: [PATCH 28/32] prima implementazione classe Database --- src/Memory/Database.cpp | 55 ++++++------ src/Memory/Database.h | 20 ++--- src/Memory/MediaContainer.cpp | 156 ---------------------------------- src/Memory/MediaContainer.h | 68 +++++---------- src/src.pro | 41 +++++++++ 5 files changed, 94 insertions(+), 246 deletions(-) delete mode 100644 src/Memory/MediaContainer.cpp create mode 100644 src/src.pro diff --git a/src/Memory/Database.cpp b/src/Memory/Database.cpp index 4744e0b..a205b2b 100644 --- a/src/Memory/Database.cpp +++ b/src/Memory/Database.cpp @@ -1,51 +1,44 @@ #include "Database.h" +#include +#include + +#include "Deserializer.h" namespace memory { -DataBase::~DataBase() { - // può darsi che se ne occupi il distruttore di QFile - // comportamento di default: per ora metto che non vengono salvati i - // cambiamenti - close(false); +Database::~Database() { + close(false); // di default non salvare eventuali cambiamenti } -int DataBase::open(const QString &path) { - // QFile.close() non lancia errori se il file non è stato aperto - // file_.commit(); - file_.setFileName(path); - if (!file_.open(QIODevice::ReadOnly | QIODevice::Text)) { - // TODO(alessandro): possiamo creare una qualche enum per i codici di errore - return 1; +bool Database::open(const QString &path) { + QFile file(path); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + return false; } - return 0; + media_container_.addMedia(Deserializer::deserialize(file)); + file.close(); + return true; } -int DataBase::close(bool save_on_exit) { +bool Database::close(bool save_on_exit) { if (save_on_exit) { - // ritorna false se c'è stato un errore. Possiamo voler cambiare il tipo di - // ritorno del metodo. - file_.commit(); - } else { - // void cancelWriting() - file_.cancelWriting(); + return file_.commit(); // false <=> errore } - return 0; + file_.cancelWriting(); + return true; } -int DataBase::save() { - // ritorna false in caso di fallimento +bool Database::save() { if (!file_.commit()) { // errore in scrittura - return -1; + return false; } - // riapri il file dopo averlo chiuso - // ritorna false in caso di fallimento + if (!file_.open(QIODevice::ReadOnly | QIODevice::Text)) { - return 1; + return false; } - return 0; + return true; } -// qua possiamo volendo utilizzare riferimenti costanti al posto di puntatori -std::vector DataBase::filterMedia( - const media::Media *media_as_filter) { +std::vector> Database::filterMedia( + const media::Media &media_as_filter) { return media_container_.filter(media_as_filter); } diff --git a/src/Memory/Database.h b/src/Memory/Database.h index d327857..ea95c0a 100644 --- a/src/Memory/Database.h +++ b/src/Memory/Database.h @@ -3,24 +3,22 @@ #include #include "./MediaContainer.h" +#include namespace memory { -class DataBase { +class Database { private: MediaContainer media_container_; QSaveFile file_; - // possiamo mettere open, close e save privati e poi usare un tipo di observer - // pattern per chiamare le funzioni. public: - DataBase() = default; - ~DataBase(); - int open(const QString &path); - int close(bool save); - int save(); - // TODO(alessandro): smart pointer - // possiamo cambiarlo a riferimenti costanti - std::vector filterMedia(const media::Media *); + ~Database(); + + bool open(const QString &path); + bool close(bool save); + bool save(); + + std::vector> filterMedia(const media::Media &); }; } // namespace memory #endif diff --git a/src/Memory/MediaContainer.cpp b/src/Memory/MediaContainer.cpp deleted file mode 100644 index 7d9c177..0000000 --- a/src/Memory/MediaContainer.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include "MediaContainer.h" - -namespace memory { - -void MediaContainer::addMedia(const std::shared_ptr& media) { - if (!media) return; - - data_[static_cast(MediaType::All)].push_back(media); - - MediaType type = determineType(media); - if (type != MediaType::All) { - data_[static_cast(type)].push_back(media); - } -} - -void MediaContainer::removeMedia(const std::shared_ptr& media) { - if (!media) return; - - for (auto& vec : data_) { - vec.erase(std::remove_if(vec.begin(), vec.end(), - [&](const std::shared_ptr& m) { - return typeid(*m) == typeid(*media) && *m == *media; - }), vec.end()); - } -} - -void MediaContainer::clear() { - for (auto& vec : data_) { - vec.clear(); - } -} - -const std::vector>& MediaContainer::getAll() const { - return data_[static_cast(MediaType::All)]; -} - -const std::vector>& MediaContainer::getByType(MediaType type) const { - return data_[static_cast(type)]; -} - -const std::vector>& MediaContainer::getByTypeAndSubtype(MediaType type) const { - std::vector> result; - - switch (type) { - case MediaType::Novel: - result.insert(result.end(), data_[static_cast(MediaType::Novel)].begin(), data_[static_cast(MediaType::Novel)].end()); - result.insert(result.end(), data_[static_cast(MediaType::EBook)].begin(), data_[static_cast(MediaType::EBook)].end()); - result.insert(result.end(), data_[static_cast(MediaType::AudioBook)].begin(), data_[static_cast(MediaType::AudioBook)].end()); - break; - case MediaType::Movie: - result.insert(result.end(), data_[static_cast(MediaType::Movie)].begin(), data_[static_cast(MediaType::Movie)].end()); - result.insert(result.end(), data_[static_cast(MediaType::Series)].begin(), data_[static_cast(MediaType::Series)].end()); - break; - case MediaType::All: - result = data_[0]; - break; - default: - result = data_[static_cast(type)]; - break; - } - - return result; -} - -MediaType MediaContainer::determineType(const std::shared_ptr& media) const { - if (std::dynamic_pointer_cast(media)) return MediaType::Series; - if (std::dynamic_pointer_cast(media)) return MediaType::Movie; - if (std::dynamic_pointer_cast(media)) return MediaType::AudioBook; - if (std::dynamic_pointer_cast(media)) return MediaType::EBook; - if (std::dynamic_pointer_cast(media)) return MediaType::Novel; - if (std::dynamic_pointer_cast(media)) return MediaType::Album; - return MediaType::All; -} - -std::vector> MediaContainer::filter(const media::Media& media) const { - std::shared_ptr mediaPtr = std::make_shared(media); - - if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); - if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); - if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); - if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); - if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); - if (auto m = std::dynamic_pointer_cast(mediaPtr)) return filters(m); - return filters(mediaPtr); -} - -std::vector> MediaContainer::filters(const std::shared_ptr& media) const { - auto allMedia = getAll(); - return media->filter(allMedia); -} - -std::vector> MediaContainer::filters(const std::shared_ptr& novel) const { - auto media = getByTypeAndSubtype(MediaType::Novel); - std::vector> allNovel; - for (const auto& m : media) - if (auto ptr = std::dynamic_pointer_cast(m)) allNovel.push_back(ptr); - std::vector> result; - for (const auto& m : novel->filter(allNovel)) result.push_back(m); - return result; -} - -std::vector> MediaContainer::filters(const std::shared_ptr& album) const { - auto media = getByType(MediaType::Album); - std::vector> allAlbum; - for (const auto& m : media) - if (auto ptr = std::dynamic_pointer_cast(m)) allAlbum.push_back(ptr); - std::vector> result; - for (const auto& m : album->filter(allAlbum)) result.push_back(m); - return result; -} - -std::vector> MediaContainer::filters(const std::shared_ptr& movie) const { - auto media = getByTypeAndSubtype(MediaType::Movie); - std::vector> allMovie; - for (const auto& m : media) - if (auto ptr = std::dynamic_pointer_cast(m)) allMovie.push_back(ptr); - std::vector> result; - for (const auto& m : movie->filter(allMovie)) result.push_back(m); - return result; -} - -std::vector> MediaContainer::filters(const std::shared_ptr& ebook) const { - auto media = getByType(MediaType::EBook); - std::vector> allEbook; - for (const auto& m : media) - if (auto ptr = std::dynamic_pointer_cast(m)) allEbook.push_back(ptr); - std::vector> result; - for (const auto& m : ebook->filter(allEbook)) result.push_back(m); - return result; -} - -std::vector> MediaContainer::filters(const std::shared_ptr& audiobook) const { - auto media = getByType(MediaType::AudioBook); - std::vector> allAudio; - for (const auto& m : media) - if (auto ptr = std::dynamic_pointer_cast(m)) allAudio.push_back(ptr); - std::vector> result; - for (const auto& m : audiobook->filter(allAudio)) result.push_back(m); - return result; -} - -std::vector> MediaContainer::filters(const std::shared_ptr& series) const { - auto media = getByType(MediaType::Series); - std::vector> allSeries; - for (const auto& m : media) - if (auto ptr = std::dynamic_pointer_cast(m)) allSeries.push_back(ptr); - std::vector> result; - for (const auto& m : series->filter(allSeries)) result.push_back(m); - return result; -} - -int MediaContainer::serialize(QSaveFile& file) const { - return Serializer::Serialize(getAll(), file); -} - -} // namespace memory diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index c4d5938..d00eb13 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -1,64 +1,36 @@ #ifndef MEMORY_MEDIACONTAINER_H #define MEMORY_MEDIACONTAINER_H +#include #include -#include #include -#include -#include -#include +#include -#include "Media.h" -#include "Novel.h" -#include "Album.h" -#include "Movie.h" -#include "Ebook.h" -#include "AudioBook.h" -#include "Series.h" -#include "Serializer.h" +#include "../Media/Album.h" +#include "../Media/AudioBook.h" +#include "../Media/Ebook.h" +#include "../Media/Movie.h" +#include "../Media/Novel.h" +#include "../Media/Series.h" namespace memory { -enum class MediaType { - All = 0, - Novel, - Album, - Movie, - EBook, - AudioBook, - Series, - Count -}; - class MediaContainer { -private: - std::array>, static_cast(MediaType::Count)> data_; - - MediaType determineType(const std::shared_ptr& media) const; - - std::vector> filters(const std::shared_ptr& media) const; - std::vector> filters(const std::shared_ptr& novel) const; - std::vector> filters(const std::shared_ptr& album) const; - std::vector> filters(const std::shared_ptr& movie) const; - std::vector> filters(const std::shared_ptr& ebook) const; - std::vector> filters(const std::shared_ptr& audiobook) const; - std::vector> filters(const std::shared_ptr& series) const; + private: - const std::vector>& getAll() const; - const std::vector>& getByType(MediaType type) const; - const std::vector>& getByTypeAndSubtype(MediaType type) const; + public: + void addMedia(const media::Media& media); + void addMedia(const std::vector&); // placeholder + void removeMedia(const media::Media& media); + void clear(); -public: - void addMedia(const std::shared_ptr& media); - void removeMedia(const std::shared_ptr& media); - void clear(); - - // Filtri - std::vector> filter(const media::Media& media) const; + // Filtri + std::vector> filter( + const media::Media& media) const; - int serialize(QSaveFile& file) const; + int serialize(QSaveFile& file) const; }; -} // namespace memory +} // namespace memory -#endif // MEMORY_MEDIACONTAINER_H +#endif // MEMORY_MEDIACONTAINER_H diff --git a/src/src.pro b/src/src.pro new file mode 100644 index 0000000..ba5f2c5 --- /dev/null +++ b/src/src.pro @@ -0,0 +1,41 @@ +###################################################################### +# Automatically generated by qmake (3.1) Tue May 20 17:32:43 2025 +###################################################################### + +TEMPLATE = app +TARGET = src +INCLUDEPATH += . +QT += widgets + +# You can make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# Please consult the documentation of the deprecated API in order to know +# how to port your code away from it. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +# Input +HEADERS += Media/Album.h \ + Media/AudioBook.h \ + Media/Ebook.h \ + Media/IConstMediaVisitor.h \ + Media/IMedia.h \ + Media/Media.h \ + Media/Movie.h \ + Media/Novel.h \ + Media/Series.h \ + Media/StringUtils.h \ + Memory/Database.h \ + Memory/Deserializer.h \ + Memory/MediaContainer.h \ + Memory/Serializer.h +SOURCES += main.cpp \ + Media/Album.cpp \ + Media/AudioBook.cpp \ + Media/Ebook.cpp \ + Media/Media.cpp \ + Media/Movie.cpp \ + Media/Novel.cpp \ + Media/Series.cpp \ + Memory/Database.cpp \ + Memory/MediaContainer.cpp From 1bfe4a8912214a4f5d392e40938f651bcee1f98b Mon Sep 17 00:00:00 2001 From: Steva0 Date: Wed, 21 May 2025 12:19:26 +0200 Subject: [PATCH 29/32] Modifica firma metodo --- src/Memory/MediaContainer.cpp | 9 +++++++-- src/Memory/MediaContainer.h | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Memory/MediaContainer.cpp b/src/Memory/MediaContainer.cpp index f00fddf..97eaadc 100644 --- a/src/Memory/MediaContainer.cpp +++ b/src/Memory/MediaContainer.cpp @@ -54,10 +54,15 @@ const std::vector& MediaContainer::getAll() const { return data_[static_cast(Type::All)]; } -const std::vector& MediaContainer::getByType(Type type) const { - return data_[static_cast(type)]; +std::vector MediaContainer::getByType(Type type) const { + std::vector result; + for (const auto& media : data_[static_cast(type)]) { + result.push_back(&media); + } + return result; } + std::vector MediaContainer::getByGroup(Type type) const { std::vector result; diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index 620176a..9fb85f4 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -32,7 +32,7 @@ class MediaContainer { std::array, static_cast(Type::TypeCount)> data_; Type detectType(const media::Media& media) const; - const std::vector& getByType(Type type) const; + std::vector getByType(Type type) const; std::vector getByGroup(Type type) const; public: From 8b3c51353625d4df5e75d9c78433c6a4d43c4b91 Mon Sep 17 00:00:00 2001 From: Steva0 Date: Wed, 21 May 2025 12:22:54 +0200 Subject: [PATCH 30/32] tolti size_t messi int --- src/Memory/MediaContainer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Memory/MediaContainer.cpp b/src/Memory/MediaContainer.cpp index 97eaadc..53ca87d 100644 --- a/src/Memory/MediaContainer.cpp +++ b/src/Memory/MediaContainer.cpp @@ -51,12 +51,12 @@ void MediaContainer::clear() { } const std::vector& MediaContainer::getAll() const { - return data_[static_cast(Type::All)]; + return data_[static_cast(Type::All)]; } std::vector MediaContainer::getByType(Type type) const { std::vector result; - for (const auto& media : data_[static_cast(type)]) { + for (const auto& media : data_[static_cast(type)]) { result.push_back(&media); } return result; @@ -67,7 +67,7 @@ std::vector MediaContainer::getByGroup(Type type) const { std::vector result; auto appendGroup = [&](Type t) { - for (const auto& media : data_[static_cast(t)]) { + for (const auto& media : data_[static_cast(t)]) { result.push_back(&media); } }; From 68f2f1e9c8540332648f0026ea213e0af014666b Mon Sep 17 00:00:00 2001 From: Steva0 Date: Wed, 21 May 2025 12:43:51 +0200 Subject: [PATCH 31/32] Aggiunto metodo clone e tolto slicing --- src/Media/Album.cpp | 5 ++ src/Media/Album.h | 2 + src/Media/AudioBook.cpp | 4 ++ src/Media/AudioBook.h | 2 + src/Media/Ebook.cpp | 4 ++ src/Media/Ebook.h | 2 + src/Media/IMedia.h | 1 + src/Media/Media.cpp | 5 ++ src/Media/Media.h | 3 ++ src/Media/Movie.cpp | 5 ++ src/Media/Movie.h | 2 + src/Media/Novel.cpp | 4 ++ src/Media/Novel.h | 2 + src/Media/Series.cpp | 5 ++ src/Media/Series.h | 2 + src/Memory/MediaContainer.cpp | 90 ++++++++++++++++------------------- src/Memory/MediaContainer.h | 8 ++-- src/Memory/Serializer.h | 2 +- 18 files changed, 95 insertions(+), 53 deletions(-) diff --git a/src/Media/Album.cpp b/src/Media/Album.cpp index ec5da60..ef163d7 100644 --- a/src/Media/Album.cpp +++ b/src/Media/Album.cpp @@ -26,6 +26,11 @@ bool Album::operator==(const Media &other) const { return false; } +std::unique_ptr Album::clone() const { + return std::make_unique(*this); +} + + bool Album::filter(const Media& album) const { // Riutilizzo filtro base di Media if (!Media::filter(album)) diff --git a/src/Media/Album.h b/src/Media/Album.h index ca30cd3..6efe82a 100644 --- a/src/Media/Album.h +++ b/src/Media/Album.h @@ -20,6 +20,8 @@ class Album : public Media { const std::vector &getSongs() const; bool operator==(const Media &other) const override; + std::unique_ptr clone() const override; + bool filter(const Media& album) const override; }; diff --git a/src/Media/AudioBook.cpp b/src/Media/AudioBook.cpp index 51ba54f..f9d91f8 100644 --- a/src/Media/AudioBook.cpp +++ b/src/Media/AudioBook.cpp @@ -21,6 +21,10 @@ bool AudioBook::operator==(const Media& other) const { return false; } +std::unique_ptr AudioBook::clone() const { + return std::make_unique(*this); +} + std::string AudioBook::getNarrator() const { return narrator_; } diff --git a/src/Media/AudioBook.h b/src/Media/AudioBook.h index e383e0c..2012e99 100644 --- a/src/Media/AudioBook.h +++ b/src/Media/AudioBook.h @@ -26,6 +26,8 @@ class AudioBook : public Novel { void setNarrator(const std::string& narrator); void setStreamingService(const std::string& service); + std::unique_ptr clone() const override; + bool filter(const Media& audiobook) const override; }; diff --git a/src/Media/Ebook.cpp b/src/Media/Ebook.cpp index d75ddc5..cb4d562 100644 --- a/src/Media/Ebook.cpp +++ b/src/Media/Ebook.cpp @@ -36,6 +36,10 @@ void Ebook::setDrm(bool drm) { drm_ = drm; } +std::unique_ptr Ebook::clone() const { + return std::make_unique(*this); +} + bool Ebook::filter(const Media& input) const { // Riutilizzo filtro base di Novel if (!Novel::filter(input)) diff --git a/src/Media/Ebook.h b/src/Media/Ebook.h index 1c8dc01..e277746 100644 --- a/src/Media/Ebook.h +++ b/src/Media/Ebook.h @@ -25,6 +25,8 @@ class Ebook : public Novel { void setFileSizeBytes(unsigned int size); void setDrm(bool drm); + std::unique_ptr clone() const override; + bool filter(const Media& ebook) const override; }; diff --git a/src/Media/IMedia.h b/src/Media/IMedia.h index d2ffa8b..677381b 100644 --- a/src/Media/IMedia.h +++ b/src/Media/IMedia.h @@ -8,6 +8,7 @@ namespace media { class IMedia { virtual void accept(IConstMediaVisitor &) const = 0; virtual bool open() = 0; + virtual std::unique_ptr clone() const = 0; }; } diff --git a/src/Media/Media.cpp b/src/Media/Media.cpp index 33d81f8..3e7b8dc 100644 --- a/src/Media/Media.cpp +++ b/src/Media/Media.cpp @@ -18,6 +18,11 @@ Media::Media(const std::string &title, int release, const std::string &language, void Media::accept(IConstMediaVisitor &v) const {} +std::unique_ptr media::Media::clone() const { + return std::make_unique(*this); +} + + bool Media::operator==(const Media &other) const { return title_ == other.title_ && release_ == other.release_ && language_ == other.language_ && favourite_ == other.favourite_ && diff --git a/src/Media/Media.h b/src/Media/Media.h index 621efd5..7d607c4 100644 --- a/src/Media/Media.h +++ b/src/Media/Media.h @@ -44,6 +44,9 @@ class Media : IMedia{ const std::string &getImgPath() const; const std::string &getNotes() const; + virtual std::unique_ptr clone() const; + + virtual bool filter(const Media &media) const; }; } // namespace media diff --git a/src/Media/Movie.cpp b/src/Media/Movie.cpp index 82f541b..59652ab 100644 --- a/src/Media/Movie.cpp +++ b/src/Media/Movie.cpp @@ -18,6 +18,11 @@ bool Movie::operator==(const Media &other) const { } return false; } + +std::unique_ptr Movie::clone() const { + return std::make_unique(*this); +} + const std::vector &Movie::getCast() const { return cast_; } unsigned int Movie::getLength() const { return length_; } const std::string &Movie::getUniverse() const { return universe_; } diff --git a/src/Media/Movie.h b/src/Media/Movie.h index 2d96c7a..19a50d7 100644 --- a/src/Media/Movie.h +++ b/src/Media/Movie.h @@ -24,6 +24,8 @@ class Movie : public Media { unsigned int getLength() const; const std::string &getUniverse() const; + std::unique_ptr clone() const override; + bool filter(const Media& movie) const override; }; } // namespace media diff --git a/src/Media/Novel.cpp b/src/Media/Novel.cpp index 3368c4e..361585c 100644 --- a/src/Media/Novel.cpp +++ b/src/Media/Novel.cpp @@ -19,6 +19,10 @@ bool Novel::operator==(const Media& other) const { return false; } +std::unique_ptr Novel::clone() const { + return std::make_unique(*this); +} + // Getters std::string Novel::getAuthor() const { return author_; } std::string Novel::getPublisher() const { return publisher_; } diff --git a/src/Media/Novel.h b/src/Media/Novel.h index edab6b5..6fa0ad5 100644 --- a/src/Media/Novel.h +++ b/src/Media/Novel.h @@ -35,6 +35,8 @@ class Novel : public Media { void setSeries(const std::string& series); void setIsbn(const std::string& isbn); + std::unique_ptr clone() const override; + bool filter(const Media &novel) const override; }; diff --git a/src/Media/Series.cpp b/src/Media/Series.cpp index d9cdcac..f0fa1a9 100644 --- a/src/Media/Series.cpp +++ b/src/Media/Series.cpp @@ -21,6 +21,11 @@ bool Series::operator==(const Media &other) const { } return false; } + +std::unique_ptr Series::clone() const { + return std::make_unique(*this); +} + unsigned int Series::getEpisodes() const { return episodes_; } unsigned int Series::getSeasons() const { return seasons_; } bool Series::isEnded() const { return ended_; } diff --git a/src/Media/Series.h b/src/Media/Series.h index fedbda6..73fa611 100644 --- a/src/Media/Series.h +++ b/src/Media/Series.h @@ -20,6 +20,8 @@ class Series : public Movie { unsigned int getEpisodes() const; unsigned int getSeasons() const; bool isEnded() const; + + std::unique_ptr clone() const override; bool filter(const Media& input) const override; }; diff --git a/src/Memory/MediaContainer.cpp b/src/Memory/MediaContainer.cpp index 53ca87d..41ac200 100644 --- a/src/Memory/MediaContainer.cpp +++ b/src/Memory/MediaContainer.cpp @@ -5,41 +5,33 @@ namespace memory { void MediaContainer::addMedia(const media::Media& media) { - data_[static_cast(Type::All)].push_back(media); + std::unique_ptr clone = media.clone(); + Type t = detectType(*clone); - Type t = detectType(media); + // Inserisci nel contenitore "All" + data_[static_cast(Type::All)].push_back(media.clone()); + + // Inserisci anche nel tipo specifico if (t != Type::All) { - data_[static_cast(t)].push_back(media); + data_[static_cast(t)].push_back(std::move(clone)); } } MediaContainer::Type MediaContainer::detectType(const media::Media& media) const { - if (dynamic_cast(&media)) { - return Type::Series; - } - if (dynamic_cast(&media)) { - return Type::AudioBook; - } - if (dynamic_cast(&media)) { - return Type::Ebook; - } - if (dynamic_cast(&media)) { - return Type::Movie; - } - if (dynamic_cast(&media)) { - return Type::Album; - } - if (dynamic_cast(&media)) { - return Type::Novel; - } + if (dynamic_cast(&media)) return Type::Series; + if (dynamic_cast(&media)) return Type::AudioBook; + if (dynamic_cast(&media)) return Type::Ebook; + if (dynamic_cast(&media)) return Type::Movie; + if (dynamic_cast(&media)) return Type::Album; + if (dynamic_cast(&media)) return Type::Novel; return Type::All; } void MediaContainer::removeMedia(const media::Media& media) { for (auto& vec : data_) { vec.erase(std::remove_if(vec.begin(), vec.end(), - [&](const media::Media& m) { - return typeid(m) == typeid(media) && m == media; + [&](const std::unique_ptr& m) { + return typeid(*m) == typeid(media) && *m == media; }), vec.end()); } } @@ -50,47 +42,43 @@ void MediaContainer::clear() { } } -const std::vector& MediaContainer::getAll() const { - return data_[static_cast(Type::All)]; +std::vector MediaContainer::getAll() const { + return getByType(Type::All); } std::vector MediaContainer::getByType(Type type) const { std::vector result; - for (const auto& media : data_[static_cast(type)]) { - result.push_back(&media); + for (const auto& ptr : data_[static_cast(type)]) { + result.push_back(ptr.get()); } return result; } - std::vector MediaContainer::getByGroup(Type type) const { std::vector result; auto appendGroup = [&](Type t) { - for (const auto& media : data_[static_cast(t)]) { - result.push_back(&media); + for (const auto& ptr : data_[static_cast(t)]) { + result.push_back(ptr.get()); } }; switch (type) { - case Type::Novel: - appendGroup(Type::Novel); - appendGroup(Type::Ebook); - appendGroup(Type::AudioBook); - break; - - case Type::Movie: - appendGroup(Type::Movie); - appendGroup(Type::Series); - break; - - case Type::All: - appendGroup(Type::All); - break; - - default: - appendGroup(type); - break; + case Type::Novel: + appendGroup(Type::Novel); + appendGroup(Type::Ebook); + appendGroup(Type::AudioBook); + break; + case Type::Movie: + appendGroup(Type::Movie); + appendGroup(Type::Series); + break; + case Type::All: + appendGroup(Type::All); + break; + default: + appendGroup(type); + break; } return result; @@ -108,7 +96,11 @@ std::vector MediaContainer::filter(const media::Media& medi } int MediaContainer::serialize(QSaveFile& file) const { - return Serializer::Serialize(data_[static_cast(Type::All)], file); + std::vector rawAll; + for (const auto& ptr : data_[static_cast(Type::All)]) { + rawAll.push_back(ptr.get()); + } + return Serializer::Serialize(rawAll, file); } } // namespace memory diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index 9fb85f4..80aee54 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -3,6 +3,7 @@ #include #include +#include #include #include "../Media/Media.h" @@ -29,12 +30,13 @@ class MediaContainer { TypeCount }; - std::array, static_cast(Type::TypeCount)> data_; + std::array>, static_cast(Type::TypeCount)> data_; Type detectType(const media::Media& media) const; + std::vector getByType(Type type) const; std::vector getByGroup(Type type) const; - + public: void addMedia(const media::Media& media); void removeMedia(const media::Media& media); @@ -42,7 +44,7 @@ class MediaContainer { std::vector filter(const media::Media& media) const; - const std::vector& getAll() const; + std::vector getAll() const; int serialize(QSaveFile& file) const; }; diff --git a/src/Memory/Serializer.h b/src/Memory/Serializer.h index 40ea2bd..cecc7d7 100644 --- a/src/Memory/Serializer.h +++ b/src/Memory/Serializer.h @@ -11,7 +11,7 @@ class Serializer { static int vecToXML(const media::Media&, QSaveFile &){} public: - static int Serialize(const std::vector&, QSaveFile &){} + static int Serialize(std::vector, QSaveFile &){} }; } // namespace memory #endif From d7f1916e661dc91b863d869edabc40f97fa77a9e Mon Sep 17 00:00:00 2001 From: Steva0 Date: Wed, 21 May 2025 12:59:03 +0200 Subject: [PATCH 32/32] Tolto doppio clone in add MEdia --- src/Memory/MediaContainer.cpp | 18 ++++++++++-------- src/Memory/MediaContainer.h | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Memory/MediaContainer.cpp b/src/Memory/MediaContainer.cpp index 41ac200..1cff655 100644 --- a/src/Memory/MediaContainer.cpp +++ b/src/Memory/MediaContainer.cpp @@ -6,17 +6,19 @@ namespace memory { void MediaContainer::addMedia(const media::Media& media) { std::unique_ptr clone = media.clone(); - Type t = detectType(*clone); + media::Media* rawPtr = clone.get(); - // Inserisci nel contenitore "All" - data_[static_cast(Type::All)].push_back(media.clone()); + // Inserisce rawPtr nel vettore "All" copiando il puntatore (non l’oggetto!) + data_[static_cast(Type::All)].push_back(std::unique_ptr(clone->clone())); - // Inserisci anche nel tipo specifico + // Inserisco anche nel tipo specifico + Type t = detectType(*clone); if (t != Type::All) { - data_[static_cast(t)].push_back(std::move(clone)); + data_[static_cast(t)].push_back(std::move(clone)); } } + MediaContainer::Type MediaContainer::detectType(const media::Media& media) const { if (dynamic_cast(&media)) return Type::Series; if (dynamic_cast(&media)) return Type::AudioBook; @@ -48,7 +50,7 @@ std::vector MediaContainer::getAll() const { std::vector MediaContainer::getByType(Type type) const { std::vector result; - for (const auto& ptr : data_[static_cast(type)]) { + for (const auto& ptr : data_[static_cast(type)]) { result.push_back(ptr.get()); } return result; @@ -58,7 +60,7 @@ std::vector MediaContainer::getByGroup(Type type) const { std::vector result; auto appendGroup = [&](Type t) { - for (const auto& ptr : data_[static_cast(t)]) { + for (const auto& ptr : data_[static_cast(t)]) { result.push_back(ptr.get()); } }; @@ -97,7 +99,7 @@ std::vector MediaContainer::filter(const media::Media& medi int MediaContainer::serialize(QSaveFile& file) const { std::vector rawAll; - for (const auto& ptr : data_[static_cast(Type::All)]) { + for (const auto& ptr : data_[static_cast(Type::All)]) { rawAll.push_back(ptr.get()); } return Serializer::Serialize(rawAll, file); diff --git a/src/Memory/MediaContainer.h b/src/Memory/MediaContainer.h index 80aee54..7b26273 100644 --- a/src/Memory/MediaContainer.h +++ b/src/Memory/MediaContainer.h @@ -30,7 +30,7 @@ class MediaContainer { TypeCount }; - std::array>, static_cast(Type::TypeCount)> data_; + std::array>, static_cast(Type::TypeCount)> data_; Type detectType(const media::Media& media) const;