summaryrefslogtreecommitdiff
path: root/src/modlistview.h
blob: 1d8a9b499e3787e08b594242771a73a21a98b329 (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
#ifndef MODLISTVIEW_H
#define MODLISTVIEW_H

#include <vector>

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

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

namespace Ui { class MainWindow; }

class OrganizerCore;
class Profile;
class ModListByPriorityProxy;

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
  };

public:
  explicit ModListView(QWidget* parent = 0);
  void setModel(QAbstractItemModel* model) override;

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

  // 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;

  // retrieve the next/previous mod in the current view, the given index
  // should be a mod index (not a model row), and the return value will be
  // a mod index or -1 if no mod was found
  //
  int nextMod(int index) const;
  int prevMod(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);

  // emitted when selected mods must be removed
  //
  void removeSelectedMods();

public slots:

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

  // enable/disable all selected mods
  //
  void enableSelected();
  void disableSelected();

  // 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();

protected:

  // 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;

  // all index for the given model under the given index, recursively
  //
  QModelIndexList allIndex(
    const QAbstractItemModel* model, int column = 0, const QModelIndex& index = QModelIndex()) const;

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

  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:

private:

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

  // 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);

  enum GroupBy {
    NONE = 0,
    CATEGORY = 1,
    NEXUS_ID = 2
  };

private:

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

    // the mod counter
    QLCDNumber* counter;

    // the text filter and clear filter button
    QLineEdit* filter;
    QPushButton* clearFilters;
  };

  OrganizerCore* m_core;
  ModListViewUi ui;

  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