summaryrefslogtreecommitdiff
path: root/src/modlistview.h
blob: a2e8505d36c6b19c7affb459b2e949647a382012 (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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
#ifndef MODLISTVIEW_H
#define MODLISTVIEW_H

#include <vector>

#include <QLabel>
#include <QTreeView>
#include <QDragEnterEvent>
#include <QLCDNumber>

#include "qtgroupingproxy.h"
#include "viewmarkingscrollbar.h"
#include "modlistsortproxy.h"

namespace Ui { class MainWindow; }

class CategoryFactory;
class FilterList;
class OrganizerCore;
class MainWindow;
class Profile;
class ModListByPriorityProxy;
class ModListViewActions;

class ModListView : public QTreeView
{
  Q_OBJECT

public:

  // this is a public version of DropIndicatorPosition
  enum DropPosition {
    OnItem = DropIndicatorPosition::OnItem,
    AboveItem = DropIndicatorPosition::AboveItem,
    BelowItem = DropIndicatorPosition::BelowItem,
    OnViewport = DropIndicatorPosition::OnViewport
  };

  // indiucate the groupby mode
  enum class GroupByMode {
    NONE,
    SEPARATOR,
    CATEGORY,
    NEXUS_ID
  };

public:
  explicit ModListView(QWidget* parent = 0);

  void setup(OrganizerCore& core, CategoryFactory& factory, MainWindow* mw, Ui::MainWindow* mwui);

  // restore/save the state between session
  //
  void restoreState(const Settings& s);
  void saveState(Settings& s) const;

  // set the current profile
  //
  void setProfile(Profile* profile);

  // check if collapsible separators are currently used
  //
  bool hasCollapsibleSeparators() const;

  // the column by which the mod list is currently sorted
  //
  int sortColumn() const;

  // the current group mode
  //
  GroupByMode groupByMode() const;

  // retrieve the actions from the view
  //
  ModListViewActions& actions() const;

  // retrieve the next/previous mod in the current view, the given index
  // should be a mod index (not a model row)
  //
  std::optional<unsigned int> nextMod(unsigned int index) const;
  std::optional<unsigned int> prevMod(unsigned int index) const;

  // check if the given mod is visible
  //
  bool isModVisible(unsigned int index) const;
  bool isModVisible(ModInfo::Ptr mod) const;

  // re-implemented to fix indentation with collapsible separators
  //
  QRect visualRect(const QModelIndex& index) const override;

  // refresh the view (to call when settings have been changed)
  //
  void refresh();

signals:

  void dragEntered(const QMimeData* mimeData);
  void dropEntered(const QMimeData* mimeData, DropPosition position);

public slots:

  // enable/disable all visible mods
  //
  void enableAllVisible();
  void disableAllVisible();

  // set the filter criteria/options for mods
  //
  void setFilterCriteria(const std::vector<ModListSortProxy::Criteria>& criteria);
  void setFilterOptions(ModListSortProxy::FilterMode mode, ModListSortProxy::SeparatorsMode sep);

  // update the mod counter
  //
  void updateModCount();

  // refresh the filters
  //
  void refreshFilters();

protected:

  friend class ModListContextMenu;
  friend class ModListViewActions;

  // map from/to the view indexes to the model
  //
  QModelIndex indexModelToView(const QModelIndex& index) const;
  QModelIndexList indexModelToView(const QModelIndexList& index) const;
  QModelIndex indexViewToModel(const QModelIndex& index) const;
  QModelIndexList indexViewToModel(const QModelIndexList& index) const;

  // returns the next/previous index of the given index
  //
  QModelIndex nextIndex(const QModelIndex& index) const;
  QModelIndex prevIndex(const QModelIndex& index) const;

  // re-implemented to fake the return value to allow drag-and-drop on
  // itself for separators
  //
  QModelIndexList selectedIndexes() const;

  // drop from external folder
  //
  void onExternalFolderDropped(const QUrl& url, int priority);

  // method to react to various key events
  //
  bool moveSelection(int key);
  bool removeSelection();
  bool toggleSelectionState();

  void timerEvent(QTimerEvent* event) override;
  void dragEnterEvent(QDragEnterEvent* event) override;
  void dragMoveEvent(QDragMoveEvent* event) override;
  void dropEvent(QDropEvent* event) override;
  bool event(QEvent* event) override;

protected slots:

  void onCustomContextMenuRequested(const QPoint& pos);
  void onDoubleClicked(const QModelIndex& index);
  void onSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
  void onFiltersCriteria(const std::vector<ModListSortProxy::Criteria>& filters);

private:

  void onModPrioritiesChanged(std::vector<int> const& indices);
  void onModInstalled(const QString& modName);
  void onModFilterActive(bool filterActive);

  // get/set the selected items on the view, this method return/take indices
  // from the mod list model, not the view, so it's safe to restore
  //
  std::pair<QModelIndex, QModelIndexList> selected() const;
  void setSelected(const QModelIndex& current, const QModelIndexList& selected);

  // call expand() after fixing the index if it comes from the source
  // of the proxy
  //
  void expandItem(const QModelIndex& index);

  // refresh the group-by proxy, if the index is -1 will refresh the
  // current one (e.g. when changing the sort column)
  //
  void updateGroupByProxy(int groupIndex);

  // index in the groupby combo
  //
  enum GroupBy {
    NONE = 0,
    CATEGORY = 1,
    NEXUS_ID = 2
  };

private:

  struct ModListViewUi
  {
    // the group by combo box
    QComboBox* groupBy;

    // the mod counter
    QLCDNumber* counter;

    // filters related
    QLineEdit* filter;
    QLabel* currentCategory;
    QPushButton* clearFilters;
    QComboBox* filterSeparators;
  };

  OrganizerCore* m_core;
  std::unique_ptr<FilterList> m_filters;
  CategoryFactory* m_categories;
  ModListViewUi ui;
  ModListViewActions* m_actions;

  ModListSortProxy* m_sortProxy;
  ModListByPriorityProxy* m_byPriorityProxy;

  QtGroupingProxy* m_byCategoryProxy;
  QtGroupingProxy* m_byNexusIdProxy;

  ViewMarkingScrollBar* m_scrollbar;

  bool m_inDragMoveEvent = false;

  // replace the auto-expand timer from QTreeView to avoid
  // auto-collapsing
  QBasicTimer m_openTimer;

};

#endif // MODLISTVIEW_H