1 #pragma once
2 
3 #ifndef DV_ITEM_VIEW_INCLUDED
4 #define DV_ITEM_VIEW_INCLUDED
5 
6 // TnzQt includes
7 #include "toonzqt/selection.h"
8 #include "toonzqt/lineedit.h"
9 
10 // TnzCore includes
11 #include "tfilepath.h"
12 
13 // Qt includes
14 #include <QWidget>
15 #include <QScrollArea>
16 #include <QToolBar>
17 
18 // STD includes
19 #include <set>
20 
21 //==============================================================
22 
23 //    Forward declarations
24 
25 class DvItemViewer;
26 class DvItemSelection;
27 class QMimeData;
28 
29 //==============================================================
30 
31 //=============================================================================
32 
33 class DvItemListModel {
34 public:
35   enum DataType {
36     Name,
37     Thumbnail,
38     Icon,
39     ToolTip,
40     CreationDate,
41     ModifiedDate,
42     FileSize,
43     FrameCount,
44     FullPath,
45     PlayAvailable,
46     VersionControlStatus,
47     FileType,
48     IsFolder
49   };
50 
51   enum Status {
52     VC_None = 0,
53     VC_ReadOnly,
54     VC_Edited,
55     VC_Modified,
56     VC_ToUpdate,
57     VC_Locked,
58     VC_Unversioned,
59     VC_Missing,
60     VC_PartialEdited,
61     VC_PartialLocked,
62     VC_PartialModified
63   };
64 
65 public:
DvItemListModel()66   DvItemListModel() : m_isDiscendent(true), m_orderType(Name) {}
~DvItemListModel()67   virtual ~DvItemListModel() {}
68 
getCurrentOrderType()69   DataType getCurrentOrderType() { return m_orderType; }
isDiscendentOrder()70   bool isDiscendentOrder() { return m_isDiscendent; }
setIsDiscendentOrder(bool isDiscendentOrder)71   void setIsDiscendentOrder(bool isDiscendentOrder) {
72     m_isDiscendent = isDiscendentOrder;
73   }
setOrderType(DataType dataType)74   void setOrderType(DataType dataType) { m_orderType = dataType; }
75 
76   // n.b. refreshData viene chiamato PRIMA di getItemCount() e getItemData()
77   // vanno messe dentro refreshData() le operazioni "costose" di getItemData() e
78   // getItemCount()
refreshData()79   virtual void refreshData(){};
80   virtual int getItemCount() const = 0;
81   virtual int compareData(DataType dataType, int firstIndex, int secondIndex);
sortByDataModel(DataType dataType,bool isDiscendent)82   virtual void sortByDataModel(DataType dataType, bool isDiscendent) {}
83   virtual QVariant getItemData(int index, DataType dataType,
84                                bool isSelected = false) = 0;
85   virtual QString getItemDataAsString(int index, DataType dataType);
86   virtual QString getItemDataIdentifierName(DataType dataType);
startDragDrop()87   virtual void startDragDrop() {}
getContextMenu(QWidget * parent,int index)88   virtual QMenu *getContextMenu(QWidget *parent, int index) { return 0; }
enableSelectionCommands(TSelection * selection)89   virtual void enableSelectionCommands(TSelection *selection) {}
canRenameItem(int index)90   virtual bool canRenameItem(int index) const { return false; }
renameItem(int index,const QString & newName)91   virtual void renameItem(int index, const QString &newName) {}
isSceneItem(int index)92   virtual bool isSceneItem(int index) const { return false; }
acceptDrop(const QMimeData * data)93   virtual bool acceptDrop(const QMimeData *data) const { return false; }
drop(const QMimeData * data)94   virtual bool drop(const QMimeData *data) { return false; }
95 
96 protected:
97   bool m_isDiscendent;
98   DataType m_orderType;
99 };
100 
101 //=============================================================================
102 
103 class ItemViewPlayWidget final : public QWidget {
104   Q_OBJECT
105 
106   int m_currentItemIndex;  //-1 -> pause
107   int m_timerId;
108   bool m_isSliderMode;
109 
110   class PlayManager {
111     TFilePath m_path;
112     std::vector<TFrameId> m_fids;
113     int m_currentFidIndex;
114     QPixmap m_pixmap;
115     QSize m_iconSize;
116 
117   public:
118     PlayManager();
~PlayManager()119     ~PlayManager() {}
120 
121     void reset();
122     void setInfo(DvItemListModel *model, int index);
123     /*! Increase current frame if icon is computed; return true if frame is
124      * increased. */
125     bool increaseCurrentFrame();
126     /*! If icon is computed return true, overwise start to compute it. */
127     bool getCurrentFrame();
128     /*! Return true if current frame index is less than fids size. */
129     bool isFrameIndexInRange();
130     bool setCurrentFrameIndexFromXValue(int xValue, int length);
131     double currentFrameIndexToXValue(int length);
132     QPixmap getCurrentPixmap();
133   };
134 
135   PlayManager *m_playManager;
136 
137 public:
138   ItemViewPlayWidget(QWidget *parent = 0);
~ItemViewPlayWidget()139   ~ItemViewPlayWidget() {}
140 
141   void play();
142   void stop();
143   void clear();
144 
145   void setIsPlaying(DvItemListModel *model, int index);
146   void setIsPlayingCurrentFrameIndex(DvItemListModel *model, int index,
147                                      int xValue, int length);
148   int getCurrentFramePosition(int length);
149 
isIndexPlaying(int index)150   bool isIndexPlaying(int index) { return m_currentItemIndex == index; }
isPlaying()151   bool isPlaying() { return m_currentItemIndex != -1; }
isSliderMode()152   bool isSliderMode() { return m_isSliderMode; }
153 
154   void paint(QPainter *painter, QRect rect);
155 
156 protected:
157   void timerEvent(QTimerEvent *event) override;
158 };
159 
160 //=============================================================================
161 
162 class DVItemViewPlayDelegate final : public QObject {
163   Q_OBJECT
164 
165   ItemViewPlayWidget *m_itemViewPlay;
166 
167 public:
168   DVItemViewPlayDelegate(QWidget *parent);
~DVItemViewPlayDelegate()169   ~DVItemViewPlayDelegate() {}
170 
171   void paint(QPainter *painter, QRect rect, int index);
172 
173   bool setPlayWidget(DvItemListModel *model, int index, QRect rect, QPoint pos);
174 
175 public slots:
176 
177   void resetPlayWidget();
178 
179 protected:
180   QRect getPlayButtonRect(QRect rect);
181   QRect getPlaySliderRect(QRect rect);
182 };
183 
184 //=============================================================================
185 
186 class DvItemSelection : public QObject, public TSelection {
187   Q_OBJECT
188 
189   std::set<int> m_selectedIndices;
190   DvItemListModel *m_model;
191 
192 public:
193   DvItemSelection();
194 
195   void select(int index, bool on = true);
196   void select(int *indices, int indicesCount);
197   void selectNone() override;
198   void selectAll();
199 
isSelected(int index)200   bool isSelected(int index) const {
201     return m_selectedIndices.count(index) > 0;
202   }
isEmpty()203   bool isEmpty() const override { return m_selectedIndices.empty(); }
204 
getSelectedIndices()205   const std::set<int> &getSelectedIndices() const { return m_selectedIndices; }
206 
207   void setModel(DvItemListModel *model);
getModel()208   DvItemListModel *getModel() const { return m_model; }
209 
210   void enableCommands() override;
211 
212 signals:
213 
214   void itemSelectionChanged();
215 };
216 
217 //=============================================================================
218 
219 class DvItemViewerPanel final : public QFrame, public TSelection::View {
220   Q_OBJECT
221 
222   QColor m_alternateBackground;     // alaternate bg color for teble view
223                                     // (170,170,170)
224   QColor m_textColor;               // text color (black)
225   QColor m_selectedTextColor;       // selected item text color (white)
226   QColor m_folderTextColor;         // folder item text color (blue)
227   QColor m_selectedItemBackground;  // selected item background color (0,0,128)
228 
229   Q_PROPERTY(QColor AlternateBackground READ getAlternateBackground WRITE
230                  setAlternateBackground)
231   Q_PROPERTY(QColor TextColor READ getTextColor WRITE setTextColor)
232   Q_PROPERTY(QColor SelectedTextColor READ getSelectedTextColor WRITE
233                  setSelectedTextColor)
234   Q_PROPERTY(
235       QColor FolderTextColor READ getFolderTextColor WRITE setFolderTextColor)
236   Q_PROPERTY(QColor SelectedItemBackground READ getSelectedItemBackground WRITE
237                  setSelectedItemBackground)
238 
239 public:
240   enum ViewType { ListView = 0, TableView, ThumbnailView };
setAlternateBackground(const QColor & color)241   void setAlternateBackground(const QColor &color) {
242     m_alternateBackground = color;
243   }
getAlternateBackground()244   QColor getAlternateBackground() const { return m_alternateBackground; }
setTextColor(const QColor & color)245   void setTextColor(const QColor &color) { m_textColor = color; }
getTextColor()246   QColor getTextColor() const { return m_textColor; }
setSelectedTextColor(const QColor & color)247   void setSelectedTextColor(const QColor &color) {
248     m_selectedTextColor = color;
249   }
getSelectedTextColor()250   QColor getSelectedTextColor() const { return m_selectedTextColor; }
setFolderTextColor(const QColor & color)251   void setFolderTextColor(const QColor &color) { m_folderTextColor = color; }
getFolderTextColor()252   QColor getFolderTextColor() const { return m_folderTextColor; }
setSelectedItemBackground(const QColor & color)253   void setSelectedItemBackground(const QColor &color) {
254     m_selectedItemBackground = color;
255   }
getSelectedItemBackground()256   QColor getSelectedItemBackground() const { return m_selectedItemBackground; }
257 
258 private:
to_enum(int n)259   ViewType to_enum(int n) {
260     switch (n) {
261     case 0:
262       return ListView;
263     case 1:
264       return TableView;
265     case 2:
266       return ThumbnailView;
267     default:
268       return ThumbnailView;
269     }
270   }
271 
272   DvItemSelection *m_selection;
273   bool m_globalSelectionEnabled;
274   bool m_multiSelectionEnabled;
275 
276   DvItemViewer *m_viewer;
277 
278   DVItemViewPlayDelegate *m_itemViewPlayDelegate;
279   bool m_isPlayDelegateDisable;
280 
281   DVGui::LineEdit *m_editFld;
282   ViewType m_viewType;
283   bool m_singleColumnEnabled;
284   bool m_centerAligned;
285 
286   // view parameters
287   int m_itemSpacing;
288   int m_xMargin, m_yMargin, m_itemPerRow;
289   QSize m_itemSize;
290   QSize m_iconSize;
291   bool m_noContextMenu;
292   void updateViewParameters(int panelWidth);
updateViewParameters()293   void updateViewParameters() { updateViewParameters(width()); }
294   QPoint m_startDragPosition;
295   QPoint m_lastMousePos;
296   int m_currentIndex;
297   std::vector<std::pair<DvItemListModel::DataType, std::pair<int, bool>>>
298       m_columns;  // type, <width, visibility>
299   DvItemListModel *getModel() const;
getItemCount()300   int getItemCount() const {
301     return getModel() ? getModel()->getItemCount() : 0;
302   }
303   QColor m_missingColor;
304 
305 public:
306   DvItemViewerPanel(DvItemViewer *viewer, bool noContextMenu,
307                     bool multiselectionEnabled, QWidget *parent);
308 
enableGlobalSelection(bool enabled)309   void enableGlobalSelection(bool enabled) {
310     if (!enabled) m_selection->makeNotCurrent();
311     m_globalSelectionEnabled = enabled;
312   }
313 
314   void setItemViewPlayDelegate(DVItemViewPlayDelegate *playDelegate);
315   DVItemViewPlayDelegate *getItemViewPlayDelegate();
316 
317   void addColumn(DvItemListModel::DataType dataType, int width);
318   void setColumnWidth(DvItemListModel::DataType dataType, int width);
getColumns(std::vector<std::pair<DvItemListModel::DataType,std::pair<int,bool>>> & columns)319   void getColumns(
320       std::vector<std::pair<DvItemListModel::DataType, std::pair<int, bool>>>
321           &columns) {
322     columns = m_columns;
323   };
324   bool getVisibility(DvItemListModel::DataType dataType);
325   void setVisibility(DvItemListModel::DataType dataType, bool value);
326   int getContentMinimumWidth();
327   int getContentHeight(int width);
328 
329   QSize getItemSize() const;
330 
getIconSize()331   QSize getIconSize() const { return m_iconSize; }
332 
333   int pos2index(const QPoint &pos) const;
334   QRect index2pos(int index) const;
335 
336   QRect getCaptionRect(int index) const;
337 
338   void paintThumbnailItem(QPainter &p, int index);
339   void paintListItem(QPainter &p, int index);
340   void paintTableItem(QPainter &p, int index);
341 
342   // da TSelection::View
onSelectionChanged()343   void onSelectionChanged() override { update(); }
344 
345   const std::set<int> &getSelectedIndices() const;
346 
enableSingleColumn(bool enabled)347   void enableSingleColumn(bool enabled) { m_singleColumnEnabled = enabled; }
isSingleColumnEnabled()348   bool isSingleColumnEnabled() const { return m_singleColumnEnabled; }
349 
setAlignCenter()350   void setAlignCenter() { m_centerAligned = true; }
351 
getSelection()352   DvItemSelection *getSelection() const { return m_selection; }
353   void setSelection(DvItemSelection *selection);  // gets ownership
354   void setMissingTextColor(const QColor &color);
355 
356 protected:
357   void paintEvent(QPaintEvent *) override;
358   void mousePressEvent(QMouseEvent *) override;
359   void mouseMoveEvent(QMouseEvent *) override;
360   void mouseReleaseEvent(QMouseEvent *) override;
361   void mouseDoubleClickEvent(QMouseEvent *) override;
362   void contextMenuEvent(QContextMenuEvent *) override;
363   bool event(QEvent *event) override;
364 
365 signals:
366   void viewTypeChange(DvItemViewerPanel::ViewType viewType);
367 
368 public slots:
369   void setListView();
370   void setTableView();
371   void setThumbnailsView();
372   void rename();
373   // for exporting the file information to text format file
374   void exportFileList();
375 };
376 
377 //=============================================================================
378 
379 class DvItemViewer : public QScrollArea {
380   Q_OBJECT
381 
382 public:
383   enum WindowType { Browser = 0, Cast };
384   WindowType m_windowType;
385 
386 private:
387   DvItemListModel *m_model;
388   DvItemViewerPanel *m_panel;
389 
390 protected:
391   void resizeEvent(QResizeEvent *) override;
392 
393 public:
394   DvItemViewer(QWidget *parent, bool noContextMenu = false,
395                bool multiSelectionEnabled = false, enum WindowType = Browser);
396 
397   void resetVerticalScrollBar();
getModel()398   DvItemListModel *getModel() const { return m_model; }
399   void setModel(DvItemListModel *model);  // gets ownership
400 
getSelectedIndices()401   const std::set<int> &getSelectedIndices() const {
402     return m_panel->getSelectedIndices();
403   }
404 
405   void updateContentSize();
406   void refresh();
407 
getPanel()408   DvItemViewerPanel *getPanel() { return m_panel; }
409 
draw(QPainter & p)410   virtual void draw(QPainter &p) {}
notifyClick(int index)411   void notifyClick(int index) {
412     emit clickedItem(index);
413     emit selectedItems(m_panel->getSelectedIndices());
414   }
notifyDoubleClick(int index)415   void notifyDoubleClick(int index) {
416     emit doubleClickedItem(index);
417     emit selectedItems(m_panel->getSelectedIndices());
418   }
419 
enableGlobalSelection(bool enabled)420   void enableGlobalSelection(bool enabled) {
421     m_panel->enableGlobalSelection(enabled);
422   }
423   void selectNone();
424   void keyPressEvent(QKeyEvent *event) override;
425 
426 protected:
427   void dragEnterEvent(QDragEnterEvent *event) override;
428   void dropEvent(QDropEvent *event) override;
429 
430 signals:
431   void clickedItem(int index);
432   void doubleClickedItem(int index);
433   void selectedItems(const std::set<int> &indexes);
434 };
435 
436 //=============================================================================
437 
438 class DvItemViewerTitleBar final : public QWidget {
439   Q_OBJECT
440 
441   DvItemViewer *m_itemViewer;
442   bool m_isInteractive;
443   int m_dragColumnIndex;
444   QPoint m_pos;
445 
446   QColor m_colColor;
447   QColor m_colSortedColor;
448   QColor m_colTextColor;
449   QColor m_colBorderColor;
450   QColor m_colRaisedColor;
451 
452   Q_PROPERTY(QColor ColColor READ getColColor WRITE setColColor);
453   Q_PROPERTY(QColor ColSortedColor READ getColColor WRITE setColSortedColor);
454   Q_PROPERTY(QColor ColTextColor READ getColColor WRITE setColTextColor);
455   Q_PROPERTY(QColor ColBorderColor READ getColColor WRITE setColBorderColor);
456   Q_PROPERTY(
457       QColor ColRaisedColor READ getColRaisedColor WRITE setColRaisedColor);
458 
459 public:
setColColor(const QColor & color)460   void setColColor(const QColor &color) { m_colColor = color; }
getColColor()461   QColor getColColor() const { return m_colColor; }
setColSortedColor(const QColor & color)462   void setColSortedColor(const QColor &color) { m_colSortedColor = color; }
getColSortedColor()463   QColor getColSortedColor() const { return m_colSortedColor; }
setColTextColor(const QColor & color)464   void setColTextColor(const QColor &color) { m_colTextColor = color; }
getColTextColor()465   QColor getColTextColor() const { return m_colTextColor; }
setColBorderColor(const QColor & color)466   void setColBorderColor(const QColor &color) { m_colBorderColor = color; }
getColBorderColor()467   QColor getColBorderColor() const { return m_colBorderColor; }
setColRaisedColor(const QColor & color)468   void setColRaisedColor(const QColor &color) { m_colRaisedColor = color; }
getColRaisedColor()469   QColor getColRaisedColor() const { return m_colRaisedColor; }
470 
471   DvItemViewerTitleBar(DvItemViewer *itemViewer, QWidget *parent = 0,
472                        bool isInteractive = true);
473 
474 protected slots:
475   void onViewTypeChanged(DvItemViewerPanel::ViewType viewType);
476 
477 protected:
478   void mouseMoveEvent(QMouseEvent *) override;
479   void openContextMenu(QMouseEvent *);
480   void mousePressEvent(QMouseEvent *) override;
481   void paintEvent(QPaintEvent *) override;
482 };
483 
484 //=============================================================================
485 
486 class DvItemViewerButtonBar final : public QToolBar {
487   Q_OBJECT
488   QAction *m_folderBack;
489   QAction *m_folderFwd;
490 
491 public:
492   DvItemViewerButtonBar(DvItemViewer *itemViewer, QWidget *parent = 0);
493 
494 public slots:
495   void onHistoryChanged(bool, bool);
496   void onPreferenceChanged(const QString &);
497 
498 signals:
499   void folderUp();
500   void newFolder();
501   void folderBack();
502   void folderFwd();
503 };
504 
505 #endif  // DV_ITEM_VIEW_INCLUDED
506