summaryrefslogtreecommitdiff
path: root/src/pluginlist.h
diff options
context:
space:
mode:
authorTannin <Tannin@Serenity>2013-02-03 12:49:25 +0100
committerTannin <Tannin@Serenity>2013-02-03 12:49:25 +0100
commit981f8b3acf7e76f27c02f4ced80d55b424cc7497 (patch)
tree0f504d99d1e5fe197258febff3c147d0725abda4 /src/pluginlist.h
initial commit to mercurial repository.
Corresponds to MO version 0.12.6
Diffstat (limited to 'src/pluginlist.h')
-rw-r--r--src/pluginlist.h220
1 files changed, 220 insertions, 0 deletions
diff --git a/src/pluginlist.h b/src/pluginlist.h
new file mode 100644
index 00000000..aa6d1426
--- /dev/null
+++ b/src/pluginlist.h
@@ -0,0 +1,220 @@
+/*
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This file is part of Mod Organizer.
+
+Mod Organizer is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Mod Organizer is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef PLUGINLIST_H
+#define PLUGINLIST_H
+
+#include <QString>
+#include <QListWidget>
+#include <vector>
+#include <directoryentry.h>
+
+
+/**
+ * @brief model representing the plugins (.esp/.esm) in the current virtual data folder
+ **/
+class PluginList : public QAbstractTableModel
+{
+ Q_OBJECT
+
+public:
+
+ enum EColumn {
+ COL_NAME,
+ COL_PRIORITY,
+ COL_MODINDEX,
+
+ COL_LASTCOLUMN = COL_MODINDEX
+ };
+
+public:
+
+ /**
+ * @brief constructor
+ *
+ * @param parent parent object
+ **/
+ PluginList(QObject *parent = NULL);
+
+ /**
+ * @brief does a complete refresh of the list
+ *
+ * @param profileName name of the current profile
+ * @param baseDirectory the root directory structure representing the virtual data directory
+ * @todo the profile is not used? If it was, we should pass the Profile-object instead
+ **/
+ void refresh(const QString &profileName, const DirectoryEntry &baseDirectory, const QString &pluginsFile, const QString &loadOrderFile, const QString &lockedOrderFile);
+
+ /**
+ * @brief enable a plugin based on its name
+ *
+ * @param name name of the plugin to enable
+ **/
+ void enableESP(const QString &name);
+
+ /**
+ * @brief test if a plugin is enabled
+ *
+ * @param name name of the plugin to look up
+ * @return true if the plugin is enabled, false otherwise
+ **/
+ bool isEnabled(const QString &name);
+
+ /**
+ * @brief test if a plugin is enabled
+ *
+ * @param index index of the plugin to look up
+ * @return true if the plugin is enabled, false otherwise
+ * @throws std::out_of_range exception is thrown if index is invalid
+ **/
+ bool isEnabled(int index);
+
+ /**
+ * @brief update the plugin status (enabled/disabled) from the specified file
+ *
+ * @param fileName path of the file to load. the filename should be "plugin.txt"
+ * @todo it would make sense to move this into the Profile-class
+ **/
+ void readEnabledFrom(const QString &fileName);
+
+ /**
+ * @brief save the plugin status to the specified file
+ *
+ * @param pluginFileName path of the plugin.txt to write to
+ * @param loadOrderFileName path of the loadorder.txt to write to
+ * @param lockedOrderFileName path of the lockedorder.txt to write to
+ * @param deleterFileName file to receive a list of files to hide from the virtual data tree. This is used to hide unchecked plugins if "hideUnchecked" is true
+ * @param hideUnchecked if true, plugins that aren't enabled will be hidden from the virtual data directory
+ **/
+ void saveTo(const QString &pluginFileName, const QString &loadOrderFileName, const QString &lockedOrderFileName,
+ const QString &deleterFileName, bool hideUnchecked) const;
+
+ /**
+ * @brief save the current load order
+ *
+ * the load order used by the game is defined by the last modification time which this
+ * function sets. An exception is newer version of skyrim where the load order is defined
+ * by the order of files in plugins.txt
+ * @param directoryStructure the root directory structure representing the virtual data directory
+ * @return true on success or if there was nothing to save, false if the load order can't be saved, i.e. because files are locked
+ * @todo since this works on actual files the load order can't be configured per-profile. Files of the same name
+ * in different mods can also have different load orders which makes this very intransparent
+ * @note also stores to disk the list of locked esps
+ **/
+ bool saveLoadOrder(DirectoryEntry &directoryStructure);
+
+ QString getName(int index) const { return m_ESPs.at(index).m_Name; }
+ int getPriority(int index) const { return m_ESPs.at(index).m_Priority; }
+ bool isESPLocked(int index) const;
+ void lockESPIndex(int index, bool lock);
+
+ bool eventFilter(QObject *obj, QEvent *event);
+
+ static QString getColumnName(int column);
+ static QString getColumnToolTip(int column);
+
+public: // implementation of the QAbstractTableModel interface
+
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const;
+ virtual Qt::DropActions supportedDropActions() const { return Qt::MoveAction; }
+ virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
+
+ void syncLoadOrder();
+public slots:
+
+ /**
+ * @brief enables ALL plugins
+ **/
+ void enableAll();
+
+ /**
+ * @brief disables ALL plugins
+ **/
+ void disableAll();
+
+signals:
+
+ /**
+ * @brief emitted when the plugin list changed, i.e. the load order was modified or a plugin was checked/unchecked
+ * @note this is currently only used to signal that there are changes that can be saved, it does
+ * not immediately cause anything to be written to disc
+ **/
+ void esplist_changed();
+
+private:
+
+ void refreshLoadOrder();
+ void updateIndices();
+
+ void writePlugins(const QString &fileName, bool writeUnchecked) const;
+ void writeLockedOrder(const QString &fileName) const;
+
+ bool readLoadOrder(const QString &fileName);
+ void readLockedOrderFrom(const QString &fileName);
+ void setPluginPriority(int row, int &newPriority);
+ void changePluginPriority(std::vector<int> rows, int newPriority);
+
+private:
+
+ struct ESPInfo {
+
+ ESPInfo(const QString &name, bool enabled, FILETIME time, const QString &originName)
+ : m_Name(name), m_Enabled(enabled), m_ForceEnabled(enabled), m_Removed(false), m_Priority(0),
+ m_LoadOrder(-1), m_Time(time), m_OriginName(originName),
+ m_IsMaster(name.endsWith("esm", Qt::CaseInsensitive)) {}
+ QString m_Name;
+ bool m_Enabled;
+ bool m_ForceEnabled;
+ bool m_Removed;
+ int m_Priority;
+ int m_LoadOrder;
+ FILETIME m_Time;
+ QString m_OriginName;
+ bool m_IsMaster;
+ };
+
+ friend bool ByName(const ESPInfo& LHS, const ESPInfo& RHS);
+ friend bool ByDate(const ESPInfo& LHS, const ESPInfo& RHS);
+ friend bool ByPriority(const ESPInfo& LHS, const ESPInfo& RHS);
+
+private:
+
+ std::vector<ESPInfo> m_ESPs;
+
+ std::map<QString, int> m_ESPsByName;
+ std::vector<int> m_ESPsByPriority;
+
+ // maps esp names to the priority specified in loadorder.txt. The esp names are
+ // all lowercase!! This is to work around the fact that BOSS for some reason writes some file with
+ // capitalization that doesn't match the actual name
+ std::map<QString, int> m_ESPLoadOrder;
+ std::map<QString, int> m_LockedOrder;
+
+ QString m_CurrentProfile;
+ mutable bool m_Modified;
+ QFontMetrics m_FontMetrics;
+
+};
+
+#endif // PLUGINLIST_H