aboutsummaryrefslogtreecommitdiff
path: root/libs/installer_fomod_plus/installer/ui/FomodViewModel.h
blob: f0ce07028e43ca9f9be6f10c6d4a29b36cb785f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#pragma once

#include <imoinfo.h>
#include <string>

#include "lib/ConditionTester.h"
#include "lib/FlagMap.h"
#include "lib/FileInstaller.h"
#include "lib/ViewModels.h"
#include "xml/FomodInfoFile.h"

/*
--------------------------------------------------------------------------------
                                Info
--------------------------------------------------------------------------------
*/
class InfoViewModel {
public:
    explicit InfoViewModel(const std::unique_ptr<FomodInfoFile>& infoFile)
    {
        if (infoFile) {
            // Copy the necessary members from FomodInfoFile to InfoViewModel
            mName    = infoFile->getName();
            mVersion = infoFile->getVersion();
            mAuthor  = infoFile->getAuthor();
            mWebsite = infoFile->getWebsite();
        }
    }

    // Accessor methods
    [[nodiscard]] std::string getName() const { return mName; }
    [[nodiscard]] std::string getVersion() const { return mVersion; }
    [[nodiscard]] std::string getAuthor() const { return mAuthor; }
    [[nodiscard]] std::string getWebsite() const { return mWebsite; }

private:
    std::string mName;
    std::string mVersion;
    std::string mAuthor;
    std::string mWebsite;
};

/*
--------------------------------------------------------------------------------
                               View Model
--------------------------------------------------------------------------------
*/
class FomodViewModel {
public:
    FomodViewModel(
        MOBase::IOrganizer* organizer,
        std::unique_ptr<ModuleConfiguration> fomodFile,
        std::unique_ptr<FomodInfoFile> infoFile);

    static std::shared_ptr<FomodViewModel> create(
        MOBase::IOrganizer* organizer,
        std::unique_ptr<ModuleConfiguration> fomodFile,
        std::unique_ptr<FomodInfoFile> infoFile);

    void forEachGroup(const std::function<void(GroupRef)>& callback) const;

    void forEachPlugin(const std::function<void(GroupRef, PluginRef)>& callback) const;

    void forEachFuturePlugin(int fromStepIndex, const std::function<void(GroupRef, PluginRef)>& callback) const;

    void selectFromJson(nlohmann::json json) const;

    void resetToDefaults();

    [[nodiscard]] std::shared_ptr<PluginViewModel> getFirstPluginForActiveStep() const;

    // Steps
    [[nodiscard]] shared_ptr_list<StepViewModel> getSteps() const { return mSteps; }
    [[nodiscard]] StepRef getActiveStep() const { return mActiveStep; }
    [[nodiscard]] int getCurrentStepIndex() const { return mCurrentStepIndex; }
    [[deprecated]] void setCurrentStepIndex(const int index) { mCurrentStepIndex = index; }

    void updateVisibleSteps() const;

    void rebuildConditionFlagsForStep(int stepIndex) const;

    void preinstall(const std::shared_ptr<MOBase::IFileTree>& tree, const QString& fomodPath);

    std::shared_ptr<FileInstaller> getFileInstaller() { return mFileInstaller; }

    std::string getDisplayImage() const;

    // Plugins
    [[nodiscard]] PluginRef getActivePlugin() const { return mActivePlugin; }

    // Info
    [[nodiscard]] std::shared_ptr<InfoViewModel> getInfoViewModel() const { return mInfoViewModel; }

    // Interactions
    void stepBack();

    void stepForward();

    bool isLastVisibleStep() const;

    bool isFirstVisibleStep() const;

    bool togglePlugin(const GroupRef, const PluginRef, bool selected) const;

    bool ctrlTogglePlugin(const GroupRef, const PluginRef, bool selected) const;

    void setActivePlugin(const PluginRef plugin) const { mActivePlugin = plugin; }

    static void markManuallySet(PluginRef plugin);

private:
    Logger& log                    = Logger::getInstance();
    MOBase::IOrganizer* mOrganizer = nullptr;
    std::unique_ptr<ModuleConfiguration> mFomodFile;
    std::unique_ptr<FomodInfoFile> mInfoFile;
    std::shared_ptr<FlagMap> mFlags{ nullptr };
    ConditionTester mConditionTester;
    std::shared_ptr<InfoViewModel> mInfoViewModel;
    std::vector<std::shared_ptr<StepViewModel> > mSteps;
    mutable std::shared_ptr<PluginViewModel> mActivePlugin{ nullptr };
    mutable std::shared_ptr<StepViewModel> mActiveStep{ nullptr };
    mutable std::vector<int> mVisibleStepIndices;
    std::shared_ptr<FileInstaller> mFileInstaller{ nullptr };
    bool mInitialized{ false };

    void createStepViewModels();

    void setFlagForPluginState(const std::shared_ptr<PluginViewModel>& plugin) const;

    static void createNonePluginForGroup(const std::shared_ptr<GroupViewModel>& group);

    void processPlugin(const std::shared_ptr<GroupViewModel>& group,
        const std::shared_ptr<PluginViewModel>& plugin) const;

    void enforceRadioGroupConstraints(const std::shared_ptr<GroupViewModel>& group) const;

    void enforceSelectAllConstraint(const std::shared_ptr<GroupViewModel>& groupViewModel) const;

    void enforceSelectAtLeastOneConstraint(const std::shared_ptr<GroupViewModel>& group) const;

    void enforceGroupConstraints() const;

    void processPluginConditions(int fromStepIndex) const;

    // Indices
    int mCurrentStepIndex{ 0 };

    void logMessage(const LogLevel level, const std::string& message) const
    {
        log.logMessage(level, "[VIEWMODEL] " + message);
    }

    std::string toString() const;
};