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