1 
2 
3 #include "dvitemview.h"
4 
5 // Tnz6 includes
6 #include "menubarcommandids.h"
7 #include "tapp.h"
8 #include "filebrowser.h"
9 
10 // TnzQt includes
11 #include "toonzqt/icongenerator.h"
12 #include "toonzqt/menubarcommand.h"
13 #include "toonzqt/tselectionhandle.h"
14 #include "toonzqt/gutil.h"
15 
16 // TnzLib includes
17 #include "toonz/toonzscene.h"
18 #include "toonz/tproject.h"
19 #include "toonz/tscenehandle.h"
20 #include "toonz/preferences.h"
21 
22 // TnzBase includes
23 #include "tenv.h"
24 
25 // TnzCore includes
26 #include "tlevel_io.h"
27 #include "tfiletype.h"
28 #include "tsystem.h"
29 
30 // Qt includes
31 #include <QMouseEvent>
32 #include <QPainter>
33 #include <QToolTip>
34 #include <QAction>
35 #include <QDate>
36 #include <QContextMenuEvent>
37 #include <QMenu>
38 #include <QScrollBar>
39 #include <QFileInfo>
40 #include <QFileDialog>
41 #include <QTextStream>
42 #include <qdrawutil.h>
43 #include <QMimeData>
44 
45 #include <stdint.h>  // for uint64_t
46 
47 TEnv::IntVar BrowserView("BrowserView", 1);
48 TEnv::IntVar CastView("CastView", 1);
49 TEnv::IntVar BrowserFileSizeisVisible("BrowserFileSizeisVisible", 1);
50 TEnv::IntVar BrowserFrameCountisVisible("BrowserFrameCountisVisible", 1);
51 TEnv::IntVar BrowserCreationDateisVisible("BrowserCreationDateisVisible", 1);
52 TEnv::IntVar BrowserModifiedDateisVisible("BrowserModifiedDateisVisible", 1);
53 TEnv::IntVar BrowserFileTypeisVisible("BrowserFileTypeisVisible", 1);
54 TEnv::IntVar BrowserVersionControlStatusisVisible(
55     "BrowserVersionControlStatusisVisible", 1);
56 
57 //************************************************************************
58 //    Local namespace  stuff
59 //************************************************************************
60 
61 namespace {
62 
getFileFids(TFilePath path,std::vector<TFrameId> & fids)63 void getFileFids(TFilePath path, std::vector<TFrameId> &fids) {
64   QFileInfo info(QString::fromStdWString(path.getWideString()));
65   TLevelP level;
66   if (info.exists()) {
67     if (path.getType() == "tnz") {
68       try {
69         ToonzScene scene;
70         scene.loadNoResources(path);
71         int i;
72         for (i = 0; i < scene.getFrameCount(); i++)
73           fids.push_back(TFrameId(i + 1));
74       } catch (...) {
75       }
76     } else if (TFileType::isViewable(TFileType::getInfo(path))) {
77       try {
78         TLevelReaderP lr(path);
79         level = lr->loadInfo();
80       } catch (...) {
81       }
82     }
83   } else if (path.isLevelName())  // for levels johndoe..tif etc.
84   {
85     try {
86       TLevelReaderP lr(path);
87       level = lr->loadInfo();
88     } catch (...) {
89     }
90   }
91   if (level.getPointer()) {
92     for (TLevel::Iterator it = level->begin(); it != level->end(); ++it)
93       fids.push_back(it->first);
94   }
95 }
96 
97 //-----------------------------------------------------------------------------
98 
hyphenText(const QString & srcText,const QFont & font,int width)99 QString hyphenText(const QString &srcText, const QFont &font, int width) {
100   QFontMetrics metrics(font);
101   int srcWidth = metrics.width(srcText);
102   if (srcWidth < width) return srcText;
103 
104   int count = double(srcWidth) / double(width);
105   int diff  = srcWidth - width * count + 4;  // +4 to keep a margin
106 
107   QString text;
108   int middleWidth = (double(width) * 0.5);
109   int i;
110   int hyphenCount = 1;
111   for (i = 0; i < srcText.size(); i++) {
112     QChar c       = srcText.at(i);
113     int cWidth    = metrics.width(c);
114     int textWidth = metrics.width(text) + cWidth;
115     if ((c.isSpace() && textWidth > (hyphenCount - 1) * width + diff) ||
116         (textWidth > hyphenCount * width)) {
117       ++hyphenCount;
118       --i;
119       text += "\n";
120     } else
121       text += c;
122   }
123   return text;
124 }
125 
getStatusPixmap(int status)126 QPixmap getStatusPixmap(int status) {
127   static QPixmap bronzePixmap     = QPixmap(":Resources/bronze.png");
128   static QPixmap plusPixmap       = QPixmap(":Resources/plus.png");
129   static QPixmap greenPixmap      = QPixmap(":Resources/green.png");
130   static QPixmap redPixmap        = QPixmap(":Resources/red.png");
131   static QPixmap orangePixmap     = QPixmap(":Resources/orange.png");
132   static QPixmap grayPixmap       = QPixmap(":Resources/gray.png");
133   static QPixmap halfGreenPixmap  = QPixmap(":Resources/halfGreen.png");
134   static QPixmap halfBronzePixmap = QPixmap(":Resources/halfBronze.png");
135   static QPixmap halfRedPixmap    = QPixmap(":Resources/halfRed.png");
136 
137   // Icon
138   if (status == DvItemListModel::VC_Locked)
139     return bronzePixmap;
140   else if (status == DvItemListModel::VC_Edited)
141     return greenPixmap;
142   else if (status == DvItemListModel::VC_ToUpdate)
143     return orangePixmap;
144   else if (status == DvItemListModel::VC_Unversioned)
145     return plusPixmap;
146   else if (status == DvItemListModel::VC_ReadOnly)
147     return grayPixmap;
148   else if (status == DvItemListModel::VC_PartialEdited)
149     return halfGreenPixmap;
150   else if (status == DvItemListModel::VC_PartialLocked)
151     return halfBronzePixmap;
152   else if (status == DvItemListModel::VC_PartialModified)
153     return halfRedPixmap;
154   else if (status == DvItemListModel::VC_Modified)
155     return redPixmap;
156   else
157     return QPixmap();
158 }
159 
160 }  // namespace
161 
162 //=============================================================================
163 //
164 // DvItemListModel
165 //
166 //-----------------------------------------------------------------------------
167 
getItemDataAsString(int index,DataType dataType)168 QString DvItemListModel::getItemDataAsString(int index, DataType dataType) {
169   QVariant value = getItemData(index, dataType);
170   if (value == QVariant()) return "";
171   switch (dataType) {
172   case Name:
173   case ToolTip:
174   case FullPath:
175     return value.toString();
176   case Thumbnail:
177   case Icon:
178     return "";
179   case CreationDate:
180     return value.toDateTime().toString(Qt::SystemLocaleShortDate);
181     break;
182   case ModifiedDate:
183     return value.toDateTime().toString(Qt::SystemLocaleShortDate);
184     break;
185   case FileSize: {
186     if (getItemData(index, IsFolder).toBool()) return QString("");
187 
188     uint64_t byteSize = value.toLongLong();
189 
190     if (byteSize < 1024) return QString::number(byteSize) + " bytes";
191 
192     int size = (byteSize) >> 10;  // divide by 1024
193 
194     if (size < 1024)
195       return QString::number(size) + " KB";
196     else if (size < 1024 * 1024)
197       return QString::number((double)size / 1024.0) + " MB";
198     else
199       return QString::number((double)size / (1024 * 1024)) + " GB";
200   } break;
201   case FrameCount: {
202     int frameCount = value.toInt();
203     return frameCount > 0 ? QString::number(frameCount) : "";
204   } break;
205   case VersionControlStatus: {
206     Status s = (Status)value.toInt();
207     switch (s) {
208     case VC_None:
209       return QObject::tr("None");
210       break;
211     case VC_Edited:
212       return QObject::tr("Edited");
213       break;
214     case VC_ReadOnly:
215       return QObject::tr("Normal");
216       break;
217     case VC_ToUpdate:
218       return QObject::tr("To Update");
219       break;
220     case VC_Modified:
221       return QObject::tr("Modified");
222       break;
223     case VC_Locked:
224       return QObject::tr("Locked");
225       break;
226     case VC_Unversioned:
227       return QObject::tr("Unversioned");
228       break;
229     case VC_Missing:
230       return QObject::tr("Missing");
231       break;
232     case VC_PartialEdited:
233       return QObject::tr("Partially Edited");
234       break;
235     case VC_PartialLocked:
236       return QObject::tr("Partially Locked");
237       break;
238     case VC_PartialModified:
239       return QObject::tr("Partially Modified");
240       break;
241     }
242     return QObject::tr("None");
243   } break;
244   case FileType:
245     return value.toString();
246   default:
247     return "";
248   }
249 }
250 
251 //-----------------------------------------------------------------------------
252 
getItemDataIdentifierName(DataType dataType)253 QString DvItemListModel::getItemDataIdentifierName(DataType dataType) {
254   switch (dataType) {
255   case Name:
256     return QObject::tr("Name");
257   case ToolTip:
258     return "";
259   case FullPath:
260     return QObject::tr("Path");
261   case Thumbnail:
262     return "";
263   case Icon:
264     return "";
265   case CreationDate:
266     return QObject::tr("Date Created");
267   case ModifiedDate:
268     return QObject::tr("Date Modified");
269   case FileSize:
270     return QObject::tr("Size");
271   case FrameCount:
272     return QObject::tr("Frames");
273   case VersionControlStatus:
274     return QObject::tr("Version Control");
275   case FileType:
276     return QObject::tr("Type");
277   default:
278     return "";
279   }
280 }
281 
282 //-----------------------------------------------------------------------------
283 
compareData(DataType dataType,int firstIndex,int secondIndex)284 int DvItemListModel::compareData(DataType dataType, int firstIndex,
285                                  int secondIndex) {
286   QVariant firstValue  = getItemData(firstIndex, dataType);
287   QVariant secondValue = getItemData(secondIndex, dataType);
288 
289   switch (dataType) {
290   case Name:
291   case FileType:
292     return QString::localeAwareCompare(firstValue.toString(),
293                                        secondValue.toString());
294 
295   case CreationDate:
296   case ModifiedDate: {
297     if (firstValue.toDateTime() < secondValue.toDateTime()) return 1;
298     if (firstValue.toDateTime() == secondValue.toDateTime()) return 0;
299     if (firstValue.toDateTime() > secondValue.toDateTime()) return -1;
300   }
301 
302   case FileSize:
303     return firstValue.toLongLong() - secondValue.toLongLong();
304 
305   case FrameCount:
306     return firstValue.toInt() - secondValue.toInt();
307 
308   case VersionControlStatus:
309     return firstValue.toInt() < secondValue.toInt();
310 
311   default:
312     break;
313   }
314 
315   return 0;
316 }
317 
318 //=============================================================================
319 //
320 // DvItemSelection
321 //
322 //-----------------------------------------------------------------------------
323 
DvItemSelection()324 DvItemSelection::DvItemSelection() : m_model(0) {}
325 
326 //-----------------------------------------------------------------------------
327 
select(int index,bool on)328 void DvItemSelection::select(int index, bool on) {
329   if (on)
330     m_selectedIndices.insert(index);
331   else
332     m_selectedIndices.erase(index);
333   emit itemSelectionChanged();
334 }
335 
336 //-----------------------------------------------------------------------------
337 
select(int * indices,int indicesCount)338 void DvItemSelection::select(int *indices, int indicesCount) {
339   m_selectedIndices.clear();
340   m_selectedIndices.insert(indices, indices + indicesCount);
341 
342   emit itemSelectionChanged();
343 }
344 
345 //-----------------------------------------------------------------------------
346 
selectNone()347 void DvItemSelection::selectNone() {
348   m_selectedIndices.clear();
349   emit itemSelectionChanged();
350 }
351 
352 //-----------------------------------------------------------------------------
353 
selectAll()354 void DvItemSelection::selectAll() {
355   m_selectedIndices.clear();
356   int i = 0;
357   for (i = 0; i < m_model->getItemCount(); i++) m_selectedIndices.insert(i);
358   emit itemSelectionChanged();
359 }
360 
361 //-----------------------------------------------------------------------------
362 
setModel(DvItemListModel * model)363 void DvItemSelection::setModel(DvItemListModel *model) { m_model = model; }
364 
365 //-----------------------------------------------------------------------------
366 
enableCommands()367 void DvItemSelection::enableCommands() {
368   if (m_model) m_model->enableSelectionCommands(this);
369 }
370 
371 //=============================================================================
372 //
373 // ItemViewPlayWidget::PlayManager
374 //
375 //-----------------------------------------------------------------------------
376 
PlayManager()377 ItemViewPlayWidget::PlayManager::PlayManager()
378     : m_path(TFilePath())
379     , m_currentFidIndex(0)
380     , m_pixmap(QPixmap())
381     , m_iconSize(QSize()) {}
382 
383 //-----------------------------------------------------------------------------
384 
reset()385 void ItemViewPlayWidget::PlayManager::reset() {
386   int i;
387   for (i = 1; i < m_fids.size(); i++)
388     IconGenerator::instance()->remove(m_path, m_fids[i]);
389   m_fids.clear();
390   m_path            = TFilePath();
391   m_currentFidIndex = 0;
392   m_pixmap          = QPixmap();
393 }
394 
395 //-----------------------------------------------------------------------------
396 
setInfo(DvItemListModel * model,int index)397 void ItemViewPlayWidget::PlayManager::setInfo(DvItemListModel *model,
398                                               int index) {
399   assert(!!model && index >= 0);
400   QString string =
401       model->getItemData(index, DvItemListModel::FullPath).toString();
402   TFilePath path = TFilePath(string.toStdWString());
403   if (!m_path.isEmpty() && !m_fids.empty() &&
404       path == m_path)  // Ho gia' il path e i frameId settati correttamente
405   {
406     m_currentFidIndex = 0;
407     m_pixmap          = QPixmap();
408     return;
409   }
410 
411   reset();
412   m_pixmap =
413       model->getItemData(index, DvItemListModel::Thumbnail).value<QPixmap>();
414   if (!m_pixmap.isNull()) m_iconSize = m_pixmap.size();
415   m_path                             = path;
416   getFileFids(m_path, m_fids);
417 }
418 
419 //-----------------------------------------------------------------------------
420 
increaseCurrentFrame()421 bool ItemViewPlayWidget::PlayManager::increaseCurrentFrame() {
422   QPixmap pixmap;
423   if (m_currentFidIndex == 0)  // Il primo fid deve essere calcolato senza tener
424                                // conto del frameId (dovrebbe esistere)
425     pixmap = (m_pixmap.isNull()) ? IconGenerator::instance()->getIcon(m_path)
426                                  : m_pixmap;
427   else
428     pixmap =
429         IconGenerator::instance()->getIcon(m_path, m_fids[m_currentFidIndex]);
430   if (pixmap.isNull())
431     return false;  // Se non ha ancora finito di calcolare l'icona ritorno
432   assert(!m_iconSize.isEmpty());
433   m_pixmap = scalePixmapKeepingAspectRatio(pixmap, m_iconSize, Qt::transparent);
434   ++m_currentFidIndex;
435   return true;
436 }
437 
438 //-----------------------------------------------------------------------------
439 
getCurrentFrame()440 bool ItemViewPlayWidget::PlayManager::getCurrentFrame() {
441   QPixmap pixmap;
442   if (m_currentFidIndex == 0)  // Il primo fid deve essere calcolato senza tener
443                                // conto del frameId (dovrebbe esistere)
444     pixmap = IconGenerator::instance()->getIcon(m_path);
445   else
446     pixmap =
447         IconGenerator::instance()->getIcon(m_path, m_fids[m_currentFidIndex]);
448   if (pixmap.isNull())
449     return false;  // Se non ha ancora finito di calcolare l'icona ritorno
450   assert(!m_iconSize.isEmpty());
451   m_pixmap = scalePixmapKeepingAspectRatio(pixmap, m_iconSize, Qt::transparent);
452   return true;
453 }
454 
455 //-----------------------------------------------------------------------------
456 
isFrameIndexInRange()457 bool ItemViewPlayWidget::PlayManager::isFrameIndexInRange() {
458   return (m_currentFidIndex >= 0 && m_currentFidIndex < m_fids.size());
459 }
460 
461 //-----------------------------------------------------------------------------
462 
setCurrentFrameIndexFromXValue(int xValue,int length)463 bool ItemViewPlayWidget::PlayManager::setCurrentFrameIndexFromXValue(
464     int xValue, int length) {
465   if (m_fids.size() == 0) return false;
466   double d     = (double)length / (double)(m_fids.size() - 1);
467   int newIndex = tround((double)xValue / d);
468   if (newIndex == m_currentFidIndex) return false;
469   m_currentFidIndex = newIndex;
470   assert(isFrameIndexInRange());
471   return true;
472 }
473 
474 //-----------------------------------------------------------------------------
475 
currentFrameIndexToXValue(int length)476 double ItemViewPlayWidget::PlayManager::currentFrameIndexToXValue(int length) {
477   if (m_fids.size() == 0) return false;
478   double d = (double)length / (double)(m_fids.size() - 1);
479   return d * m_currentFidIndex;
480 }
481 
482 //-----------------------------------------------------------------------------
483 
getCurrentPixmap()484 QPixmap ItemViewPlayWidget::PlayManager::getCurrentPixmap() { return m_pixmap; }
485 
486 //=============================================================================
487 //
488 // ItemViewPlayWidget
489 //
490 //-----------------------------------------------------------------------------
491 
ItemViewPlayWidget(QWidget * parent)492 ItemViewPlayWidget::ItemViewPlayWidget(QWidget *parent)
493     : QWidget(parent)
494     , m_currentItemIndex(-1)
495     , m_timerId(0)
496     , m_isSliderMode(false) {
497   m_playManager = new PlayManager();
498 }
499 
500 //-----------------------------------------------------------------------------
501 
play()502 void ItemViewPlayWidget::play() { m_timerId = startTimer(100); }
503 
504 //-----------------------------------------------------------------------------
505 
stop()506 void ItemViewPlayWidget::stop() {
507   if (m_timerId != 0) {
508     killTimer(m_timerId);
509     m_timerId = 0;
510   }
511   if (!m_isSliderMode) m_currentItemIndex = -1;
512 }
513 //-----------------------------------------------------------------------------
514 
clear()515 void ItemViewPlayWidget::clear() {
516   m_isSliderMode = false;
517   if (m_currentItemIndex != -1) stop();
518   m_playManager->reset();
519 }
520 
521 //-----------------------------------------------------------------------------
522 
setIsPlaying(DvItemListModel * model,int index)523 void ItemViewPlayWidget::setIsPlaying(DvItemListModel *model, int index) {
524   if (isIndexPlaying(index) &&
525       !m_isSliderMode)  // Devo fare stop prima di inizializzare un nuovo play
526   {
527     stop();
528     return;
529   } else if (m_isSliderMode) {
530     m_isSliderMode = false;
531   }
532 
533   if (m_currentItemIndex == -1) {
534     m_currentItemIndex = index;
535     m_playManager->setInfo(model, index);
536   }
537   play();
538 }
539 
540 //-----------------------------------------------------------------------------
541 
setIsPlayingCurrentFrameIndex(DvItemListModel * model,int index,int xValue,int length)542 void ItemViewPlayWidget::setIsPlayingCurrentFrameIndex(DvItemListModel *model,
543                                                        int index, int xValue,
544                                                        int length) {
545   m_isSliderMode = true;
546 
547   if (m_currentItemIndex == -1) {
548     m_currentItemIndex = index;
549     m_playManager->setInfo(model, index);
550   }
551   if (!m_playManager->setCurrentFrameIndexFromXValue(xValue, length)) return;
552   stop();  // Devo fare stop prima di cambiare il frame corrente
553   play();
554 }
555 
556 //-----------------------------------------------------------------------------
557 
getCurrentFramePosition(int length)558 int ItemViewPlayWidget::getCurrentFramePosition(int length) {
559   if (m_playManager->isFrameIndexInRange())
560     return m_playManager->currentFrameIndexToXValue(length);
561   return 0;
562 }
563 
564 //-----------------------------------------------------------------------------
565 
paint(QPainter * painter,QRect rect)566 void ItemViewPlayWidget::paint(QPainter *painter, QRect rect) {
567   QPixmap pixmap = m_playManager->getCurrentPixmap();
568   if (pixmap.isNull()) return;
569   painter->drawPixmap(rect.adjusted(2, 2, -1, -1), pixmap);
570 }
571 
572 //-----------------------------------------------------------------------------
573 
timerEvent(QTimerEvent * event)574 void ItemViewPlayWidget::timerEvent(QTimerEvent *event) {
575   if (!m_playManager->isFrameIndexInRange()) {
576     stop();
577     parentWidget()->update();
578     return;
579   }
580   if (m_isSliderMode)  // Modalita' slider
581   {
582     if (!m_playManager->getCurrentFrame()) return;
583     parentWidget()->update();
584     stop();
585     return;
586   }
587   // Modalita' play
588   if (!m_playManager->increaseCurrentFrame())
589     return;
590   else
591     parentWidget()->update();
592 }
593 
594 //=============================================================================
595 // DVItemViewPlayDelegate
596 //-----------------------------------------------------------------------------
597 
DVItemViewPlayDelegate(QWidget * parent)598 DVItemViewPlayDelegate::DVItemViewPlayDelegate(QWidget *parent)
599     : QObject(parent) {
600   m_itemViewPlay = new ItemViewPlayWidget(parent);
601 }
602 
603 //-----------------------------------------------------------------------------
604 
setPlayWidget(DvItemListModel * model,int index,QRect rect,QPoint pos)605 bool DVItemViewPlayDelegate::setPlayWidget(DvItemListModel *model, int index,
606                                            QRect rect, QPoint pos) {
607   bool isPlaying = getPlayButtonRect(rect).contains(pos);
608   if (!isPlaying && !getPlaySliderRect(rect).contains(pos)) return false;
609   if (isPlaying)
610     m_itemViewPlay->setIsPlaying(model, index);
611   else
612     m_itemViewPlay->setIsPlayingCurrentFrameIndex(
613         model, index, pos.x() - getPlaySliderRect(rect).left(),
614         getPlaySliderRect(rect).width());
615   return true;
616 }
617 
618 //-----------------------------------------------------------------------------
619 
resetPlayWidget()620 void DVItemViewPlayDelegate::resetPlayWidget() { m_itemViewPlay->clear(); }
621 
622 //-----------------------------------------------------------------------------
623 
paint(QPainter * painter,QRect rect,int index)624 void DVItemViewPlayDelegate::paint(QPainter *painter, QRect rect, int index) {
625   if (m_itemViewPlay->isIndexPlaying(index) &&
626       !m_itemViewPlay->isSliderMode())  // Modalita' play
627   {
628     QSize iconSize(10, 11);
629     static QIcon playIcon = createQIconPNG("iconpause");
630     QPixmap pixmap        = playIcon.pixmap(iconSize);
631     if (m_itemViewPlay->isIndexPlaying(index))
632       m_itemViewPlay->paint(painter, rect);
633     painter->drawPixmap(getPlayButtonRect(rect), pixmap);
634   } else {
635     QSize iconSize(6, 11);
636     static QIcon playIcon = createQIconPNG("iconplay");
637     QPixmap pixmap        = playIcon.pixmap(iconSize);
638     if (m_itemViewPlay->isIndexPlaying(
639             index))  // Puo' servire in modalita' slider
640       m_itemViewPlay->paint(painter, rect);
641     painter->drawPixmap(getPlayButtonRect(rect).adjusted(2, 0, -2, 0), pixmap);
642   }
643   QRect sliderRect = getPlaySliderRect(rect);
644   double xSliderValue =
645       sliderRect.left() +
646       m_itemViewPlay->getCurrentFramePosition(sliderRect.width()) - 1;
647   QRect indicatorRect(xSliderValue, sliderRect.top() + 2, 2, 6);
648   sliderRect = sliderRect.adjusted(0, 4, 0, -4);
649   QColor sliderColor(171, 206, 255);
650   painter->setPen(Qt::black);
651   painter->fillRect(sliderRect, QBrush(sliderColor));
652   painter->drawRect(sliderRect);
653   painter->fillRect(indicatorRect, QBrush(sliderColor));
654   painter->drawRect(indicatorRect);
655 }
656 
657 //-----------------------------------------------------------------------------
658 
getPlayButtonRect(QRect rect)659 QRect DVItemViewPlayDelegate::getPlayButtonRect(QRect rect) {
660   QPoint iconSize = QPoint(10, 11);
661   QPoint point    = rect.bottomRight() - iconSize;
662   QRect playButtonRect(point.x(), point.y(), iconSize.x(), iconSize.y());
663   return playButtonRect;
664 }
665 
666 //-----------------------------------------------------------------------------
667 
getPlaySliderRect(QRect rect)668 QRect DVItemViewPlayDelegate::getPlaySliderRect(QRect rect) {
669   QPoint point = rect.bottomLeft() + QPoint(5, -10);
670   QRect playSliderRect(point.x(), point.y(), rect.width() - 20, 10);
671   return playSliderRect;
672 }
673 
674 //=============================================================================
675 //
676 // DvItemViewerPanel
677 //
678 //-----------------------------------------------------------------------------
679 
DvItemViewerPanel(DvItemViewer * viewer,bool noContextMenu,bool multiSelectionEnabled,QWidget * parent)680 DvItemViewerPanel::DvItemViewerPanel(DvItemViewer *viewer, bool noContextMenu,
681                                      bool multiSelectionEnabled,
682                                      QWidget *parent)
683     : QFrame(parent)
684     , m_selection(0)
685     , m_viewer(viewer)
686     , m_viewType(viewer->m_windowType == DvItemViewer::Cast
687                      ? to_enum(CastView)
688                      : to_enum(BrowserView))
689     , m_xMargin(0)
690     , m_yMargin(0)
691     , m_itemSpacing(0)
692     , m_itemPerRow(0)
693     , m_itemSize(0, 0)
694     , m_iconSize(80, 60)
695     , m_currentIndex(-1)
696     , m_singleColumnEnabled(false)
697     , m_centerAligned(false)
698     , m_noContextMenu(noContextMenu)
699     , m_isPlayDelegateDisable(true)
700     , m_globalSelectionEnabled(true)
701     , m_multiSelectionEnabled(multiSelectionEnabled)
702     , m_missingColor(Qt::gray) {
703   setFrameStyle(QFrame::StyledPanel);
704   setFocusPolicy(Qt::StrongFocus);
705   // setSizePolicy(QSizePolicy::Ignored, QSizePolicy::MinimumExpanding);
706   QSizePolicy sizePolicy(QSizePolicy::Ignored, QSizePolicy::MinimumExpanding);
707   sizePolicy.setHeightForWidth(true);
708   setSizePolicy(sizePolicy);
709   m_selection = new DvItemSelection();
710   m_selection->setView(this);
711   m_selection->setModel(m_viewer->getModel());
712   connect(IconGenerator::instance(), SIGNAL(iconGenerated()), this,
713           SLOT(update()));
714 
715   m_editFld = new DVGui::LineEdit(this);
716   m_editFld->hide();
717   connect(m_editFld, SIGNAL(editingFinished()), this, SLOT(rename()));
718 
719   m_columns.push_back(
720       std::make_pair(DvItemListModel::Name, std::make_pair(200, 1)));
721 }
722 
723 //-----------------------------------------------------------------------------
724 
setItemViewPlayDelegate(DVItemViewPlayDelegate * playDelegate)725 void DvItemViewerPanel::setItemViewPlayDelegate(
726     DVItemViewPlayDelegate *playDelegate) {
727   m_isPlayDelegateDisable = false;
728   m_itemViewPlayDelegate  = playDelegate;
729 }
730 
731 //-----------------------------------------------------------------------------
732 
getItemViewPlayDelegate()733 DVItemViewPlayDelegate *DvItemViewerPanel::getItemViewPlayDelegate() {
734   if (m_isPlayDelegateDisable) return 0;
735   return m_itemViewPlayDelegate;
736 }
737 
738 //-----------------------------------------------------------------------------
739 
addColumn(DvItemListModel::DataType dataType,int width)740 void DvItemViewerPanel::addColumn(DvItemListModel::DataType dataType,
741                                   int width) {
742   bool val;
743   switch (dataType) {
744   case DvItemListModel::FileSize:
745     val = (bool)BrowserFileSizeisVisible;
746     break;
747   case DvItemListModel::FrameCount:
748     val = (bool)BrowserFrameCountisVisible;
749     break;
750   case DvItemListModel::CreationDate:
751     val = (bool)BrowserCreationDateisVisible;
752     break;
753   case DvItemListModel::ModifiedDate:
754     val = (bool)BrowserModifiedDateisVisible;
755     break;
756   case DvItemListModel::FileType:
757     val = (bool)BrowserFileTypeisVisible;
758     break;
759   case DvItemListModel::VersionControlStatus:
760     val = (bool)BrowserVersionControlStatusisVisible;
761     break;
762   default:
763     val = true;
764   }
765   m_columns.push_back(std::make_pair(dataType, std::make_pair(width, val)));
766 }
767 
768 //-----------------------------------------------------------------------------
769 
setColumnWidth(DvItemListModel::DataType dataType,int width)770 void DvItemViewerPanel::setColumnWidth(DvItemListModel::DataType dataType,
771                                        int width) {
772   int i;
773   for (i = 0; i < m_columns.size(); i++) {
774     if (m_columns[i].first != dataType)
775       continue;
776     else
777       m_columns[i].second.first = width;
778   }
779   update();
780 }
781 
782 //-----------------------------------------------------------------------------
783 
getVisibility(DvItemListModel::DataType dataType)784 bool DvItemViewerPanel::getVisibility(DvItemListModel::DataType dataType) {
785   int i;
786   for (i = 0; i < m_columns.size(); i++) {
787     if (m_columns[i].first != dataType)
788       continue;
789     else
790       return m_columns[i].second.second;
791   }
792   return 0;
793 }
794 //-----------------------------------------------------------------------------
795 
setVisibility(DvItemListModel::DataType dataType,bool value)796 void DvItemViewerPanel::setVisibility(DvItemListModel::DataType dataType,
797                                       bool value) {
798   int i;
799   for (i = 0; i < m_columns.size(); i++) {
800     if (m_columns[i].first != dataType)
801       continue;
802     else
803       m_columns[i].second.second = value;
804   }
805   switch (dataType) {
806   case DvItemListModel::FileSize:
807     BrowserFileSizeisVisible = value;
808     break;
809   case DvItemListModel::FrameCount:
810     BrowserFrameCountisVisible = value;
811     break;
812   case DvItemListModel::CreationDate:
813     BrowserCreationDateisVisible = value;
814     break;
815   case DvItemListModel::ModifiedDate:
816     BrowserModifiedDateisVisible = value;
817     break;
818   case DvItemListModel::FileType:
819     BrowserFileTypeisVisible = value;
820     break;
821   case DvItemListModel::VersionControlStatus:
822     BrowserVersionControlStatusisVisible = value;
823     break;
824   default:
825     break;
826   }
827 }
828 
829 //-----------------------------------------------------------------------------
830 
getModel() const831 DvItemListModel *DvItemViewerPanel::getModel() const {
832   return m_viewer->getModel();
833 }
834 
835 //-----------------------------------------------------------------------------
836 
setSelection(DvItemSelection * selection)837 void DvItemViewerPanel::setSelection(DvItemSelection *selection) {
838   if (m_selection == selection) return;
839   delete m_selection;
840   m_selection = selection;
841   m_selection->setModel(getModel());
842 }
843 
844 //-----------------------------------------------------------------------------
845 
getSelectedIndices() const846 const std::set<int> &DvItemViewerPanel::getSelectedIndices() const {
847   return m_selection->getSelectedIndices();
848 }
849 
850 //-----------------------------------------------------------------------------
851 
updateViewParameters(int panelWidth)852 void DvItemViewerPanel::updateViewParameters(int panelWidth) {
853   m_itemPerRow  = 1;
854   m_xMargin     = 5;
855   m_yMargin     = 5;
856   m_itemSpacing = 5;
857   int w;
858 
859   switch (m_viewType) {
860   case ListView:
861     m_itemSize    = QSize(panelWidth, fontMetrics().height());
862     m_itemSpacing = 0;
863     break;
864   case TableView: {
865     m_itemSize    = QSize(panelWidth, fontMetrics().height() + 7);
866     m_itemSpacing = 0;
867     m_xMargin     = 0;
868     m_yMargin     = 0;
869     break;
870   }
871   case ThumbnailView:
872     m_itemSize = QSize(m_iconSize.width() + 10, m_iconSize.height() + 30);
873     if (!m_singleColumnEnabled) {
874       int w        = panelWidth - m_xMargin * 2 + m_itemSpacing;
875       int iw       = m_itemSize.width() + m_itemSpacing;
876       m_itemPerRow = w / iw;
877       if (m_itemPerRow < 1) m_itemPerRow = 1;
878     }
879     w = (panelWidth + m_itemSpacing -
880          m_itemPerRow * (m_itemSize.width() + m_itemSpacing)) /
881         2;
882     if (w > m_xMargin) m_xMargin = w;
883     break;
884   }
885   if (m_centerAligned) {
886     int rowCount = (getItemCount() + m_itemPerRow - 1) / m_itemPerRow;
887     int contentHeight =
888         rowCount * (m_itemSize.height() + m_itemSpacing) - m_itemSpacing;
889     int parentHeight = parentWidget()->height();
890     if (contentHeight + 2 * m_yMargin < parentHeight)
891       m_yMargin = (parentHeight - contentHeight) / 2;
892   }
893 }
894 
895 //-----------------------------------------------------------------------------
896 
pos2index(const QPoint & pos) const897 int DvItemViewerPanel::pos2index(const QPoint &pos) const {
898   int xDist = (pos.x() - m_xMargin);
899   int col   = (xDist < 0) ? -1 : xDist / (m_itemSize.width() + m_itemSpacing);
900   int yDist = (pos.y() - m_yMargin);
901   int row   = (yDist < 0) ? -1 : yDist / (m_itemSize.height() + m_itemSpacing);
902   return row * m_itemPerRow + col;
903 }
904 
905 //-----------------------------------------------------------------------------
906 
index2pos(int index) const907 QRect DvItemViewerPanel::index2pos(int index) const {
908   int row = index / m_itemPerRow;
909   int col = index - row * m_itemPerRow;
910   QPoint pos(m_xMargin + (m_itemSize.width() + m_itemSpacing) * col,
911              m_yMargin + (m_itemSize.height() + m_itemSpacing) * row);
912   return QRect(pos, m_itemSize);
913 }
914 
915 //-----------------------------------------------------------------------------
916 
getCaptionRect(int index) const917 QRect DvItemViewerPanel::getCaptionRect(int index) const {
918   QRect itemRect = index2pos(index);
919   //  TDimension m_iconSize(80,60);// =
920   //  IconGenerator::instance()->getIconSize();
921   int y = itemRect.top() + m_iconSize.height();
922   QRect textRect(itemRect.left(), y, itemRect.width(), itemRect.bottom() - y);
923 
924   return textRect;
925 }
926 
927 //-----------------------------------------------------------------------------
928 
getContentMinimumWidth()929 int DvItemViewerPanel::getContentMinimumWidth() {
930   switch (m_viewType) {
931   case ListView:
932     return 200;
933     break;
934   case TableView:
935     return 600;
936     break;
937   case ThumbnailView:
938     return 120;
939     break;
940   default:
941     return 120;
942     break;
943   }
944 }
945 
946 //-----------------------------------------------------------------------------
947 
getContentHeight(int width)948 int DvItemViewerPanel::getContentHeight(int width) {
949   updateViewParameters(width);
950   int itemCount = getItemCount();
951   QRect rect    = index2pos(itemCount - 1);
952   return rect.bottom() + m_yMargin;
953 }
954 
955 //-----------------------------------------------------------------------------
956 
paintEvent(QPaintEvent *)957 void DvItemViewerPanel::paintEvent(QPaintEvent *) {
958   QPainter p(this);
959   int i, n = getItemCount();
960   updateViewParameters(width());
961   switch (m_viewType) {
962   case ListView:
963     for (i = 0; i < n; i++) paintListItem(p, i);
964     break;
965   case TableView:
966     for (i = 0; i < n; i++) paintTableItem(p, i);
967     break;
968   case ThumbnailView:
969     for (i = 0; i < n; i++) paintThumbnailItem(p, i);
970     break;
971   }
972 
973   /*
974 
975 p.setPen(Qt::green);
976 for(i=0;i<n;i++)
977 p.drawRect(index2pos(i));
978 
979 int y = getContentHeight(width());
980 p.drawLine(0,y,width(),y);
981 
982 p.setPen(Qt::magenta);
983 p.drawRect(0,0,width()-1,height()-1);
984 */
985 
986   m_viewer->draw(p);
987 }
988 
989 //-----------------------------------------------------------------------------
990 
setMissingTextColor(const QColor & color)991 void DvItemViewerPanel::setMissingTextColor(const QColor &color) {
992   m_missingColor = color;
993 }
994 
995 //-----------------------------------------------
996 
paintThumbnailItem(QPainter & p,int index)997 void DvItemViewerPanel::paintThumbnailItem(QPainter &p, int index) {
998   // Get Version Control Status
999   int status = getModel()
1000                    ->getItemData(index, DvItemListModel::VersionControlStatus)
1001                    .toInt();
1002 
1003   bool isSelected = m_selection->isSelected(index);
1004   QRect rect      = index2pos(index);
1005   if (!visibleRegion().intersects(rect)) return;
1006   if (!getModel()) return;
1007 
1008   QRect iconRect(rect.left() + (rect.width() - m_iconSize.width()) / 2,
1009                  rect.top(), m_iconSize.width(), m_iconSize.height());
1010   QRect textRect(iconRect.left(), iconRect.bottom(), iconRect.width(),
1011                  rect.bottom() - iconRect.bottom());
1012 
1013   // Draw Selection
1014   if (isSelected) {
1015     p.setPen(Qt::NoPen);
1016     p.fillRect(iconRect.adjusted(-2, -2, 2, 2), getSelectedItemBackground());
1017     p.fillRect(textRect.adjusted(-2, 3, 2, 0), getSelectedItemBackground());
1018   }
1019 
1020   // Draw Pixmap
1021   // if(status != DvItemListModel::VC_Missing)
1022   //{
1023 
1024   QPixmap thumbnail =
1025       getModel()
1026           ->getItemData(index, DvItemListModel::Thumbnail, isSelected)
1027           .value<QPixmap>();
1028   if (!thumbnail.isNull()) p.drawPixmap(iconRect.topLeft(), thumbnail);
1029   //}
1030   else {
1031     static QPixmap missingPixmap =
1032         QPixmap(getIconThemePath("mimetypes/60/missing_icon.svg"));
1033     QRect pixmapRect(rect.left() + (rect.width() - missingPixmap.width()) / 2,
1034                      rect.top(), missingPixmap.width(), missingPixmap.height());
1035     p.drawPixmap(pixmapRect.topLeft(), missingPixmap);
1036   }
1037 
1038   // Draw Text
1039   if (status == DvItemListModel::VC_Missing)
1040     p.setPen(m_missingColor);
1041   else
1042     p.setPen((isSelected) ? getSelectedTextColor() : getTextColor());
1043 
1044   QString name =
1045       getModel()->getItemData(index, DvItemListModel::Name).toString();
1046   int frameCount =
1047       getModel()->getItemData(index, DvItemListModel::FrameCount).toInt();
1048   if (frameCount > 0) {
1049     QString num;
1050     name += QString(" [") + num.number(frameCount) + QString("]");
1051   }
1052   QString elideName = elideText(name, p.font(), 2 * textRect.width());
1053   p.drawText(textRect, Qt::AlignCenter,
1054              hyphenText(elideName, p.font(), textRect.width()));
1055 
1056   if (isSelected) {
1057     if (!m_isPlayDelegateDisable &&
1058         getModel()->getItemData(index, DvItemListModel::PlayAvailable).toBool())
1059       m_itemViewPlayDelegate->paint(&p, iconRect.adjusted(-2, -2, 1, 1), index);
1060   }
1061 
1062   // Draw Scene rect
1063   if (getModel()->isSceneItem(index)) {
1064     QRect r(iconRect.left(), iconRect.top(), iconRect.width(), 4);
1065     p.setPen(Qt::black);
1066     p.drawRect(r.adjusted(0, 0, -1, -1));
1067     p.fillRect(r.adjusted(1, 1, -1, -1), Qt::white);
1068     p.setPen(isSelected ? Qt::blue : Qt::black);
1069     int x;
1070     for (x = r.left() + 5; x + 5 < r.right(); x += 10) {
1071       int y = r.top() + 1;
1072       p.drawLine(x, y, x + 4, y);
1073       y++;
1074       x++;
1075       p.drawLine(x, y, x + 4, y);
1076     }
1077   }
1078 
1079   if (status != DvItemListModel::VC_None &&
1080       status != DvItemListModel::VC_Missing) {
1081     QPoint iconSize = QPoint(18, 18);
1082     QPoint point    = rect.topLeft() - QPoint(1, 4);
1083     QRect pixmapRect(point.x(), point.y(), iconSize.x(), iconSize.y());
1084 
1085     QPixmap statusPixmap = getStatusPixmap(status);
1086     p.drawPixmap(pixmapRect, statusPixmap);
1087   }
1088 }
1089 
1090 //-----------------------------------------------------------------------------
1091 
paintListItem(QPainter & p,int index)1092 void DvItemViewerPanel::paintListItem(QPainter &p, int index) {
1093   QRect rect = index2pos(index);
1094   if (!visibleRegion().intersects(rect)) return;
1095   if (!getModel()) return;
1096   QPixmap icon =
1097       getModel()->getItemData(index, DvItemListModel::Icon).value<QPixmap>();
1098   QString name =
1099       getModel()->getItemData(index, DvItemListModel::Name).toString();
1100   bool isSelected = m_selection->isSelected(index);
1101   if (isSelected) p.fillRect(rect, QColor(171, 206, 255));
1102   p.drawPixmap(rect.topLeft(), icon);
1103   rect.adjust(30, 0, 0, 0);
1104   p.setPen(Qt::black);
1105   p.drawText(rect, Qt::AlignLeft | Qt::AlignVCenter,
1106              elideText(name, p.font(), rect.width()));
1107 }
1108 
1109 //-----------------------------------------------------------------------------
1110 
paintTableItem(QPainter & p,int index)1111 void DvItemViewerPanel::paintTableItem(QPainter &p, int index) {
1112   QRect rect = index2pos(index);
1113   if (!visibleRegion().intersects(rect)) return;
1114   if (!getModel()) return;
1115   bool isSelected = m_selection->isSelected(index);
1116   if (isSelected)
1117     p.fillRect(rect, getSelectedItemBackground());
1118   else if (index % 2 == 0)
1119     p.fillRect(rect, getAlternateBackground());  // 160,160,160
1120 
1121   DvItemListModel::Status status =
1122       (DvItemListModel::Status)getModel()
1123           ->getItemData(index, DvItemListModel::VersionControlStatus)
1124           .toInt();
1125 
1126   if (getModel()->getItemData(index, DvItemListModel::IsFolder).toBool())
1127     p.setPen(getFolderTextColor());
1128   else {
1129     if (status == DvItemListModel::VC_Missing)
1130       p.setPen(m_missingColor);
1131     else
1132       p.setPen((isSelected) ? getSelectedTextColor() : getTextColor());
1133   }
1134 
1135   int h  = 0;  // fontMetrics().descent();
1136   int y  = rect.top();
1137   int ly = rect.height();
1138   int x  = rect.left();
1139 
1140   int i, n = (int)m_columns.size();
1141 
1142   // Version Control status pixmap
1143   QPixmap statusPixmap = getStatusPixmap(status);
1144   if (!statusPixmap.isNull()) {
1145     p.drawPixmap(x + 1, y + 1, statusPixmap.scaled(15, 15, Qt::KeepAspectRatio,
1146                                                    Qt::SmoothTransformation));
1147     x += 15;
1148   }
1149 
1150   for (i = 0; i < n; i++) {
1151     if (!(m_columns[i].second.second)) continue;
1152     DvItemListModel::DataType dataType = m_columns[i].first;
1153     QString value = getModel()->getItemDataAsString(index, dataType);
1154     int lx        = m_columns[i].second.first;
1155     p.drawText(QRect(x + 4, y + 1, lx - 4, ly - 1),
1156                Qt::AlignLeft | Qt::AlignVCenter,
1157                elideText(value, p.font(), lx));
1158     x += lx;
1159     // If status icon is show, shift the next column left by the width of the
1160     // icon
1161     if (i == 0 && !statusPixmap.isNull()) x -= 15;
1162   }
1163   if (n > 1) {
1164     p.setPen(QColor(0, 0, 0, 100));  // column line
1165     if ((m_columns[0].second.second))
1166       x = rect.left() + m_columns[0].second.first;
1167     else
1168       x = rect.left();
1169     for (i = 1; i < n; i++) {
1170       if (!(m_columns[i].second.second)) continue;
1171       p.drawLine(x - 1, y, x - 1, y + ly);
1172       x += m_columns[i].second.first;
1173     }
1174     p.drawLine(x - 1, y, x - 1, y + ly);
1175   }
1176 }
1177 
1178 //-----------------------------------------------------------------------------
1179 
mousePressEvent(QMouseEvent * event)1180 void DvItemViewerPanel::mousePressEvent(QMouseEvent *event) {
1181   updateViewParameters(width());
1182   int index       = pos2index(event->pos());
1183   bool isSelected = m_selection->isSelected(index);
1184   if (event->button() == Qt::RightButton) {
1185     // when a folder item is right-clicked, do nothing
1186     if (getModel()->getItemData(index, DvItemListModel::IsFolder).toBool())
1187       return;
1188 
1189     if (!isSelected) {
1190       m_selection->selectNone();
1191       if (!m_isPlayDelegateDisable) m_itemViewPlayDelegate->resetPlayWidget();
1192       if (0 <= index && index < getItemCount()) m_selection->select(index);
1193       if (m_globalSelectionEnabled) m_selection->makeCurrent();
1194       update();
1195     }
1196     return;
1197   } else if (event->button() == Qt::MidButton) {
1198     m_lastMousePos = event->globalPos();
1199     event->accept();
1200     return;
1201   }
1202   if (!m_isPlayDelegateDisable) {
1203     QRect rect = index2pos(index);
1204     QRect iconRect(rect.left() + (rect.width() - m_iconSize.width()) / 2,
1205                    rect.top(), m_iconSize.width(), m_iconSize.height());
1206     DvItemListModel *model = getModel();
1207     if (model->getItemData(index, DvItemListModel::PlayAvailable).toBool() &&
1208         isSelected) {
1209       if (m_itemViewPlayDelegate->setPlayWidget(getModel(), index, iconRect,
1210                                                 event->pos())) {
1211         update();
1212         return;
1213       }
1214     } else
1215       m_itemViewPlayDelegate->resetPlayWidget();
1216   }
1217 
1218   // without any modifier, clear the selection
1219   if (!m_multiSelectionEnabled ||
1220       (0 == (event->modifiers() & Qt::ControlModifier) &&
1221        0 == (event->modifiers() & Qt::ShiftModifier) &&
1222        !m_selection->isSelected(index)))
1223     m_selection->selectNone();
1224 
1225   // if click something
1226   if (0 <= index && index < getItemCount()) {
1227     if (0 != (event->modifiers() & Qt::ControlModifier)) {
1228       // ctrl-click
1229       m_selection->select(index, !m_selection->isSelected(index));
1230     } else if (0 != (event->modifiers() & Qt::ShiftModifier)) {
1231       // shift-click
1232       if (!isSelected) {
1233         int a = index, b = index;
1234         while (a > 0 && !m_selection->isSelected(a - 1)) a--;
1235         if (a == 0) a = index;
1236         int k         = getItemCount();
1237         while (b < k && !m_selection->isSelected(b + 1)) b++;
1238         if (b == k) b = index;
1239         int i;
1240         for (i = a; i <= b; i++) {
1241           // select except folder items
1242           if (!getModel()->getItemData(i, DvItemListModel::IsFolder).toBool())
1243             m_selection->select(i);
1244         }
1245       }
1246     } else {
1247       m_selection->selectNone();
1248       m_selection->select(index);
1249     }
1250   }
1251   if (m_globalSelectionEnabled) m_selection->makeCurrent();
1252   m_currentIndex = index;
1253   if (m_viewer) m_viewer->notifyClick(index);
1254   m_startDragPosition = event->pos();
1255   update();
1256 }
1257 
1258 //-----------------------------------------------------------------------------
1259 
mouseMoveEvent(QMouseEvent * event)1260 void DvItemViewerPanel::mouseMoveEvent(QMouseEvent *event) {
1261   if (event->buttons() == Qt::MidButton) {
1262     QPoint d       = event->globalPos() - m_lastMousePos;
1263     m_lastMousePos = event->globalPos();
1264     if (m_viewer) {
1265       QScrollBar *scb = m_viewer->verticalScrollBar();
1266       scb->setValue(scb->value() - d.y());
1267     }
1268     return;
1269   }
1270   // continuo solo se il bottone sinistro e' premuto.
1271   else if (!(event->buttons() & Qt::LeftButton))
1272     return;
1273 
1274   if (!m_isPlayDelegateDisable) {
1275     int index       = pos2index(event->pos());
1276     bool isSelected = m_selection->isSelected(index);
1277     QRect rect      = index2pos(index);
1278     QRect iconRect(rect.left() + (rect.width() - m_iconSize.width()) / 2,
1279                    rect.top(), m_iconSize.width(), m_iconSize.height());
1280     DvItemListModel *model = getModel();
1281     if (model->getItemData(index, DvItemListModel::PlayAvailable).toBool() &&
1282         isSelected) {
1283       if (m_itemViewPlayDelegate->setPlayWidget(getModel(), index, iconRect,
1284                                                 event->pos())) {
1285         update();
1286         return;
1287       }
1288     } else
1289       m_itemViewPlayDelegate->resetPlayWidget();
1290   }
1291 
1292   // faccio partire il drag&drop solo se mi sono mosso di una certa quantita'
1293   if ((event->pos() - m_startDragPosition).manhattanLength() < 20) return;
1294   // e se c'e' una selezione non vuota
1295   if (m_currentIndex < 0 || m_currentIndex >= getItemCount()) return;
1296 
1297   assert(getModel());
1298   getModel()->startDragDrop();
1299 }
1300 
1301 //-----------------------------------------------------------------------------
1302 
mouseReleaseEvent(QMouseEvent *)1303 void DvItemViewerPanel::mouseReleaseEvent(QMouseEvent *) {}
1304 
1305 //-----------------------------------------------------------------------------
1306 
mouseDoubleClickEvent(QMouseEvent * event)1307 void DvItemViewerPanel::mouseDoubleClickEvent(QMouseEvent *event) {
1308   int index = pos2index(event->pos());
1309   if (index < 0 || index >= getItemCount()) return;
1310   if (m_viewer) m_viewer->notifyDoubleClick(index);
1311   if (!getModel()->canRenameItem(index)) return;
1312   QRect captionRect = getCaptionRect(index);
1313   if (!captionRect.contains(event->pos())) return;
1314   m_currentIndex = index;
1315 
1316   DVGui::LineEdit *fld = m_editFld;
1317   // getModel()->refreshData();
1318   QString name =
1319       getModel()->getItemData(index, DvItemListModel::Name).toString();
1320   fld->setText(name);
1321   fld->setGeometry(captionRect);
1322   fld->show();
1323   fld->selectAll();
1324   fld->setFocus(Qt::OtherFocusReason);
1325 }
1326 
1327 //-----------------------------------------------------------------------------
1328 
rename()1329 void DvItemViewerPanel::rename() {
1330   QString newName = m_editFld->text();
1331   m_editFld->hide();
1332   if (getModel() && 0 <= m_currentIndex && m_currentIndex < getItemCount()) {
1333     getModel()->renameItem(m_currentIndex, newName);
1334   }
1335 }
1336 
1337 //-----------------------------------------------------------------------------
1338 
contextMenuEvent(QContextMenuEvent * event)1339 void DvItemViewerPanel::contextMenuEvent(QContextMenuEvent *event) {
1340   if (!getModel()) return;
1341   if (m_noContextMenu) return;
1342 
1343   int index   = pos2index(event->pos());
1344   QMenu *menu = getModel()->getContextMenu(this, index);
1345   if (menu) {
1346     menu->exec(event->globalPos());
1347     delete menu;
1348   }
1349 }
1350 
1351 //-----------------------------------------------------------------------------
1352 
event(QEvent * event)1353 bool DvItemViewerPanel::event(QEvent *event) {
1354   if (event->type() == QEvent::ToolTip) {
1355     // getModel()->refreshData();
1356     QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
1357     int index             = pos2index(helpEvent->pos());
1358     if (0 <= index && index < getItemCount()) {
1359       QRect rect      = index2pos(index);
1360       QPoint iconSize = QPoint(18, 18);
1361       QPoint point    = rect.topLeft() - QPoint(1, 4);
1362       QRect pixmapRect(point.x(), point.y(), iconSize.x(), iconSize.y());
1363       if (pixmapRect.contains(helpEvent->pos()))
1364         QToolTip::showText(helpEvent->globalPos(),
1365                            getModel()->getItemDataAsString(
1366                                index, DvItemListModel::VersionControlStatus));
1367       else {
1368         QVariant data =
1369             getModel()->getItemData(index, DvItemListModel::ToolTip);
1370         if (data == QVariant())
1371           QToolTip::hideText();
1372         else
1373           QToolTip::showText(helpEvent->globalPos(), data.toString());
1374       }
1375     } else
1376       QToolTip::hideText();
1377   }
1378   return QWidget::event(event);
1379 }
1380 //-----------------------------------------------------------------------------
1381 
setListView()1382 void DvItemViewerPanel::setListView() {
1383   m_viewType                                                 = ListView;
1384   m_viewer->m_windowType == DvItemViewer::Cast ? CastView    = ListView
1385                                                : BrowserView = ListView;
1386   emit viewTypeChange(m_viewType);
1387   m_viewer->updateContentSize();
1388   update();
1389 }
1390 
1391 //-----------------------------------------------------------------------------
1392 
setTableView()1393 void DvItemViewerPanel::setTableView() {
1394   m_viewType                                                 = TableView;
1395   m_viewer->m_windowType == DvItemViewer::Cast ? CastView    = TableView
1396                                                : BrowserView = TableView;
1397   emit viewTypeChange(m_viewType);
1398   m_viewer->updateContentSize();
1399   update();
1400 }
1401 
1402 //-----------------------------------------------------------------------------
1403 
setThumbnailsView()1404 void DvItemViewerPanel::setThumbnailsView() {
1405   m_viewType                                                 = ThumbnailView;
1406   m_viewer->m_windowType == DvItemViewer::Cast ? CastView    = ThumbnailView
1407                                                : BrowserView = ThumbnailView;
1408   emit viewTypeChange(m_viewType);
1409   m_viewer->updateContentSize();
1410   update();
1411 }
1412 
1413 //-----------------------------------------------------------------------------
1414 
exportFileList()1415 void DvItemViewerPanel::exportFileList() {
1416   TProject *project =
1417       TProjectManager::instance()->getCurrentProject().getPointer();
1418   ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
1419   TFilePath fp;
1420   if (scene) fp = scene->decodeFilePath(project->getFolder(TProject::Extras));
1421 
1422   QString initialPath;
1423   if (fp.isEmpty())
1424     initialPath = QString();
1425   else
1426     initialPath = toQString(fp);
1427 
1428   QString fileName = QFileDialog::getSaveFileName(
1429       0, tr("Save File List"), initialPath, tr("File List (*.csv)"));
1430 
1431   if (fileName.isEmpty()) return;
1432 
1433   QFile data(fileName);
1434   if (data.open(QFile::WriteOnly)) {
1435     QTextStream out(&data);
1436 
1437     for (int index = 0; index < getItemCount(); index++) {
1438       if (getModel()->getItemData(index, DvItemListModel::IsFolder).toBool())
1439         continue;
1440 
1441       for (int i = 0; i < (int)m_columns.size(); i++) {
1442         DvItemListModel::DataType dataType = m_columns[i].first;
1443 
1444         if (dataType != DvItemListModel::Name &&
1445             dataType != DvItemListModel::FrameCount)
1446           continue;
1447 
1448         QString value = getModel()->getItemDataAsString(index, dataType);
1449 
1450         out << value;
1451         if (dataType == DvItemListModel::Name) out << ",";
1452       }
1453       out << ('\n');
1454     }
1455   }
1456   data.close();
1457 }
1458 
1459 //=============================================================================
1460 //
1461 // DvItemViewer
1462 //
1463 //-----------------------------------------------------------------------------
1464 
DvItemViewer(QWidget * parent,bool noContextMenu,bool multiSelectionEnabled,DvItemViewer::WindowType windowType)1465 DvItemViewer::DvItemViewer(QWidget *parent, bool noContextMenu,
1466                            bool multiSelectionEnabled,
1467                            DvItemViewer::WindowType windowType)
1468     : QScrollArea(parent), m_model(0) {
1469   m_windowType = windowType;
1470   m_panel =
1471       new DvItemViewerPanel(this, noContextMenu, multiSelectionEnabled, 0);
1472   setObjectName("BrowserTreeView");
1473   setStyleSheet("#BrowserTreeView {qproperty-autoFillBackground: true;}");
1474 
1475   setWidget(m_panel);
1476   setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1477   setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
1478   setAcceptDrops(true);
1479 }
1480 
1481 //-----------------------------------------------------------------------------
1482 
setModel(DvItemListModel * model)1483 void DvItemViewer::setModel(DvItemListModel *model) {
1484   if (model == m_model) return;
1485   delete m_model;
1486   m_model = model;
1487   m_panel->getSelection()->setModel(model);
1488 }
1489 
1490 //-----------------------------------------------------------------------------
1491 
updateContentSize()1492 void DvItemViewer::updateContentSize() {
1493   int w              = m_panel->getContentMinimumWidth();
1494   if (w < width()) w = width();
1495   int h              = m_panel->getContentHeight(w) +
1496           20;  // 20 is margin for showing the empty area
1497   if (h < height()) h = height();
1498   m_panel->resize(w, h);
1499 }
1500 
1501 //-----------------------------------------------------------------------------
1502 
resizeEvent(QResizeEvent * event)1503 void DvItemViewer::resizeEvent(QResizeEvent *event) {
1504   updateContentSize();
1505   QScrollArea::resizeEvent(event);
1506 }
1507 //-----------------------------------------------------------------------------
1508 
keyPressEvent(QKeyEvent * event)1509 void DvItemViewer::keyPressEvent(QKeyEvent *event) {
1510   if (event->key() == Qt::Key_Home)
1511     QScrollArea::verticalScrollBar()->setValue(0);
1512   if (event->key() == Qt::Key_End)
1513     QScrollArea::verticalScrollBar()->setValue(
1514         QScrollArea::verticalScrollBar()->maximum());
1515 
1516   QScrollArea::keyPressEvent(event);
1517 }
1518 //-----------------------------------------------------------------------------
1519 
resetVerticalScrollBar()1520 void DvItemViewer::resetVerticalScrollBar() {
1521   QScrollArea::verticalScrollBar()->setValue(0);
1522 }
1523 //-----------------------------------------------------------------------------
1524 
dragEnterEvent(QDragEnterEvent * event)1525 void DvItemViewer::dragEnterEvent(QDragEnterEvent *event) {
1526   const QMimeData *mimeData = event->mimeData();
1527   if (m_model && m_model->acceptDrop(mimeData)) {
1528     if (acceptResourceOrFolderDrop(mimeData->urls())) {
1529       // Force CopyAction
1530       event->setDropAction(Qt::CopyAction);
1531       event->accept();
1532     } else
1533       event->acceptProposedAction();
1534   }
1535 }
1536 
1537 //-----------------------------------------------------------------------------
1538 
dropEvent(QDropEvent * event)1539 void DvItemViewer::dropEvent(QDropEvent *event) {
1540   const QMimeData *mimeData = event->mimeData();
1541   if (m_model && m_model->drop(mimeData)) {
1542     if (acceptResourceOrFolderDrop(mimeData->urls())) {
1543       // Force CopyAction
1544       event->setDropAction(Qt::CopyAction);
1545       event->accept();
1546     } else
1547       event->acceptProposedAction();
1548   }
1549 }
1550 
1551 //-----------------------------------------------------------------------------
1552 
refresh()1553 void DvItemViewer::refresh() {
1554   updateContentSize();
1555   update();
1556 }
1557 
1558 //-----------------------------------------------------------------------------
1559 
selectNone()1560 void DvItemViewer::selectNone() {
1561   if (m_panel->getSelection()) m_panel->getSelection()->selectNone();
1562 }
1563 
1564 //=============================================================================
1565 //
1566 // DvItemViewTitleBar
1567 //
1568 //-----------------------------------------------------------------------------
1569 
DvItemViewerTitleBar(DvItemViewer * itemViewer,QWidget * parent,bool isInteractive)1570 DvItemViewerTitleBar::DvItemViewerTitleBar(DvItemViewer *itemViewer,
1571                                            QWidget *parent, bool isInteractive)
1572     : QWidget(parent)
1573     , m_itemViewer(itemViewer)
1574     , m_isInteractive(isInteractive)
1575     , m_pos(QPoint(0, 0))
1576     , m_dragColumnIndex(-1) {
1577   setMinimumHeight(22);
1578 
1579   bool ret = connect(m_itemViewer->getPanel(),
1580                      SIGNAL(viewTypeChange(DvItemViewerPanel::ViewType)), this,
1581                      SLOT(onViewTypeChanged(DvItemViewerPanel::ViewType)));
1582 
1583   assert(ret);
1584 
1585   setMouseTracking(true);
1586   if ((itemViewer->m_windowType == DvItemViewer::Browser &&
1587        BrowserView == DvItemViewerPanel::TableView) ||
1588       (itemViewer->m_windowType == DvItemViewer::Cast &&
1589        CastView == DvItemViewerPanel::TableView))
1590     show();
1591   else
1592     hide();
1593 }
1594 
1595 //-----------------------------------------------------------------------------
1596 
onViewTypeChanged(DvItemViewerPanel::ViewType viewType)1597 void DvItemViewerTitleBar::onViewTypeChanged(
1598     DvItemViewerPanel::ViewType viewType) {
1599   if ((m_itemViewer->m_windowType == DvItemViewer::Browser &&
1600        BrowserView == DvItemViewerPanel::TableView) ||
1601       (m_itemViewer->m_windowType == DvItemViewer::Cast &&
1602        CastView == DvItemViewerPanel::TableView))
1603     show();
1604   else
1605     hide();
1606 }
1607 
1608 //-----------------------------------------------------------------------------
1609 
mouseMoveEvent(QMouseEvent * event)1610 void DvItemViewerTitleBar::mouseMoveEvent(QMouseEvent *event) {
1611   QPoint pos = event->pos();
1612   std::vector<std::pair<DvItemListModel::DataType, std::pair<int, bool>>>
1613       columns;
1614   m_itemViewer->getPanel()->getColumns(columns);
1615   DvItemListModel *model = m_itemViewer->getModel();
1616 
1617   if (event->buttons() == Qt::NoButton) {
1618     int i, n = (int)columns.size();
1619     int x  = 0;
1620     int ly = height();
1621     for (i = 0; i < n; i++) {
1622       if (!(columns[i].second.second)) continue;
1623       int lx = columns[i].second.first;
1624       x += lx;
1625       if (abs(x - pos.x()) > 1) continue;
1626       m_dragColumnIndex = i;
1627       setCursor(Qt::SplitHCursor);
1628       return;
1629     }
1630     m_dragColumnIndex = -1;
1631     setCursor(Qt::ArrowCursor);
1632   } else if (event->buttons() == Qt::LeftButton && m_dragColumnIndex >= 0) {
1633     int delta       = pos.x() - m_pos.x();
1634     int columnWidth = columns[m_dragColumnIndex].second.first;
1635     if (columnWidth + delta < 20) return;
1636     m_itemViewer->getPanel()->setColumnWidth(columns[m_dragColumnIndex].first,
1637                                              columnWidth + delta);
1638     update();
1639     m_pos = pos;
1640   }
1641 }
1642 
1643 //-----------------------------------------------------------------------------
1644 
mousePressEvent(QMouseEvent * event)1645 void DvItemViewerTitleBar::mousePressEvent(QMouseEvent *event) {
1646   QPoint pos = event->pos();
1647   if (event->button() == Qt::LeftButton) {
1648     if (m_dragColumnIndex >= 0) {
1649       m_pos = pos;
1650       return;
1651     } else
1652       m_pos = QPoint(0, 0);
1653     if (!m_isInteractive) return;
1654     std::vector<std::pair<DvItemListModel::DataType, std::pair<int, bool>>>
1655         columns;
1656     m_itemViewer->getPanel()->getColumns(columns);
1657     DvItemListModel *model = m_itemViewer->getModel();
1658     int i, n = (int)columns.size();
1659     int x  = 0;
1660     int ly = height();
1661     for (i = 0; i < n; i++) {
1662       if (!(columns[i].second.second)) continue;
1663       int lx = columns[i].second.first;
1664       QRect columnRect(x, 0, lx, ly - 1);
1665       x += lx;
1666       if (!columnRect.contains(pos)) continue;
1667       DvItemListModel::DataType dataType = columns[i].first;
1668       model->sortByDataModel(dataType, !model->isDiscendentOrder());
1669       update();
1670     }
1671     return;
1672   }
1673   if (event->button() == Qt::RightButton) {
1674     openContextMenu(event);
1675   }
1676 }
1677 //-----------------------------------------------------------------------------
1678 
openContextMenu(QMouseEvent * event)1679 void DvItemViewerTitleBar::openContextMenu(QMouseEvent *event) {
1680   // QAction setNameAction          (QObject::tr("Name"),0);
1681   // setNameAction.setCheckable(true);
1682   // setNameAction.setChecked(m_itemViewer->getPanel()->getVisibility(DvItemListModel::Name));
1683   QAction setSizeAction(QObject::tr("Size"), 0);
1684   setSizeAction.setCheckable(true);
1685   setSizeAction.setChecked(
1686       m_itemViewer->getPanel()->getVisibility(DvItemListModel::FileSize));
1687   QAction setFramesAction(QObject::tr("Frames"), 0);
1688   setFramesAction.setCheckable(true);
1689   setFramesAction.setChecked(
1690       m_itemViewer->getPanel()->getVisibility(DvItemListModel::FrameCount));
1691   QAction setDateCreatedAction(QObject::tr("Date Created"), 0);
1692   setDateCreatedAction.setCheckable(true);
1693   setDateCreatedAction.setChecked(
1694       m_itemViewer->getPanel()->getVisibility(DvItemListModel::CreationDate));
1695   QAction setDateModifiedAction(QObject::tr("Date Modified"), 0);
1696   setDateModifiedAction.setCheckable(true);
1697   setDateModifiedAction.setChecked(
1698       m_itemViewer->getPanel()->getVisibility(DvItemListModel::ModifiedDate));
1699   QAction setTypeAction(QObject::tr("Type"), 0);
1700   setTypeAction.setCheckable(true);
1701   setTypeAction.setChecked(
1702       m_itemViewer->getPanel()->getVisibility(DvItemListModel::FileType));
1703   QAction setVersionControlAction(QObject::tr("Version Control"), 0);
1704   setVersionControlAction.setCheckable(true);
1705   setVersionControlAction.setChecked(m_itemViewer->getPanel()->getVisibility(
1706       DvItemListModel::VersionControlStatus));
1707   QMenu menu(0);
1708   // menu.addAction(&setNameAction);
1709   menu.addAction(&setFramesAction);
1710   if (m_itemViewer->m_windowType == DvItemViewer::Browser) {
1711     menu.addAction(&setSizeAction);
1712     menu.addAction(&setDateCreatedAction);
1713     menu.addAction(&setDateModifiedAction);
1714     menu.addAction(&setTypeAction);
1715     menu.addAction(&setVersionControlAction);
1716   }
1717 
1718   QAction *action = menu.exec(event->globalPos());  // QCursor::pos());
1719   // if(action==&setNameAction)
1720   // m_itemViewer->getPanel()->setVisibility(DvItemListModel::Name,!m_itemViewer->getPanel()->getVisibility(DvItemListModel::Name));
1721   if (action == &setSizeAction)
1722     m_itemViewer->getPanel()->setVisibility(
1723         DvItemListModel::FileSize,
1724         !m_itemViewer->getPanel()->getVisibility(DvItemListModel::FileSize));
1725   if (action == &setFramesAction)
1726     m_itemViewer->getPanel()->setVisibility(
1727         DvItemListModel::FrameCount,
1728         !m_itemViewer->getPanel()->getVisibility(DvItemListModel::FrameCount));
1729   if (action == &setDateCreatedAction)
1730     m_itemViewer->getPanel()->setVisibility(
1731         DvItemListModel::CreationDate, !m_itemViewer->getPanel()->getVisibility(
1732                                            DvItemListModel::CreationDate));
1733   if (action == &setDateModifiedAction)
1734     m_itemViewer->getPanel()->setVisibility(
1735         DvItemListModel::ModifiedDate, !m_itemViewer->getPanel()->getVisibility(
1736                                            DvItemListModel::ModifiedDate));
1737   if (action == &setTypeAction)
1738     m_itemViewer->getPanel()->setVisibility(
1739         DvItemListModel::FileType,
1740         !m_itemViewer->getPanel()->getVisibility(DvItemListModel::FileType));
1741   if (action == &setVersionControlAction)
1742     m_itemViewer->getPanel()->setVisibility(
1743         DvItemListModel::VersionControlStatus,
1744         !m_itemViewer->getPanel()->getVisibility(
1745             DvItemListModel::VersionControlStatus));
1746 
1747   m_itemViewer->getPanel()->update();
1748 }
1749 //-----------------------------------------------------------------------------
1750 
paintEvent(QPaintEvent *)1751 void DvItemViewerTitleBar::paintEvent(QPaintEvent *) {
1752   QPainter p(this);
1753   std::vector<std::pair<DvItemListModel::DataType, std::pair<int, bool>>>
1754       columns;
1755   m_itemViewer->getPanel()->getColumns(columns);
1756   QRect rect(0, 0, width(), height());
1757 
1758   QBrush nb    = QBrush(Qt::NoBrush);
1759   QPalette pal = QPalette(nb, nb, QBrush(QColor(getColBorderColor())),
1760                           QBrush(QColor(getColBorderColor())),
1761                           QBrush(QColor(Qt::gray)), nb, nb, nb, nb);
1762 
1763   p.fillRect(rect, getColColor());
1764 
1765   p.setPen(getColTextColor());
1766   int h  = 0;  // fontMetrics().descent();
1767   int y  = rect.top();
1768   int ly = rect.height();
1769   int lx = rect.width();
1770   int x  = rect.left();
1771 
1772   DvItemListModel *model = m_itemViewer->getModel();
1773   int i, n = (int)columns.size();
1774   for (i = 0; i < n; i++) {
1775     if (!(columns[i].second.second)) continue;
1776     DvItemListModel::DataType dataType = columns[i].first;
1777     int columnLx                       = columns[i].second.first;
1778 
1779     // paint background
1780     QColor bgColor;
1781     if (dataType == model->getCurrentOrderType())
1782       bgColor = QColor(getColSortedColor());
1783     else
1784       bgColor = QColor(0, 0, 0, 0);
1785 
1786     QRect typeRect(x - 1, y - 1, columnLx + 1, ly + 1);
1787     QBrush brush(bgColor);
1788     qDrawShadePanel(&p, typeRect, pal, false, 1, &brush);
1789 
1790     // draw ordering arrow
1791     if (m_isInteractive && dataType == model->getCurrentOrderType()) {
1792       QIcon arrowIcon;
1793       if (model->isDiscendentOrder())
1794         arrowIcon = createQIconPNG("arrow_up");
1795       else
1796         arrowIcon = createQIconPNG("arrow_down");
1797       p.drawPixmap(QRect(x + columnLx - 11, y + 6, 8, 8),
1798                    arrowIcon.pixmap(8, 8));
1799     }
1800 
1801     // draw text
1802     QString value = model->getItemDataIdentifierName(dataType);
1803     p.drawText(QRect(x + 4, y + 1, columnLx - 4, ly - 1),
1804                Qt::AlignLeft | Qt::AlignVCenter,
1805                elideText(value, p.font(), columnLx - 4));
1806 
1807     x += columnLx;
1808   }
1809 }
1810 
1811 //=============================================================================
1812 //
1813 // DvItemViewButtonBar
1814 //
1815 //-----------------------------------------------------------------------------
1816 
DvItemViewerButtonBar(DvItemViewer * itemViewer,QWidget * parent)1817 DvItemViewerButtonBar::DvItemViewerButtonBar(DvItemViewer *itemViewer,
1818                                              QWidget *parent)
1819     : QToolBar(parent) {
1820   setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
1821   setObjectName("buttonBar");
1822   setIconSize(QSize(16, 16));
1823 
1824   QIcon backButtonIcon = createQIcon("fb_back");
1825   QIcon fwdButtonIcon  = createQIcon("fb_fwd");
1826 
1827   m_folderBack = new QAction(backButtonIcon, tr("Back"), this);
1828   m_folderBack->setIconText("");
1829   addAction(m_folderBack);
1830   m_folderFwd = new QAction(fwdButtonIcon, tr("Forward"), this);
1831   m_folderFwd->setIconText("");
1832   addAction(m_folderFwd);
1833 
1834   QIcon folderUpIcon = createQIcon("fb_up");
1835   QAction *folderUp  = new QAction(folderUpIcon, tr("Up One Level"), this);
1836   folderUp->setIconText(tr("Up"));
1837   addAction(folderUp);
1838   addSeparator();
1839 
1840   QIcon newFolderIcon = createQIcon("folder_new");
1841   QAction *newFolder  = new QAction(newFolderIcon, tr("New Folder"), this);
1842   newFolder->setIconText(tr("New"));
1843   addAction(newFolder);
1844   addSeparator();
1845 
1846   // view mode
1847   QActionGroup *actions = new QActionGroup(this);
1848   actions->setExclusive(true);
1849 
1850   QIcon thumbViewIcon = createQIcon("viewicon");
1851   QAction *thumbView  = new QAction(thumbViewIcon, tr("Icons View"), this);
1852   thumbView->setCheckable(true);
1853   thumbView->setIconText(tr("Icon"));
1854   thumbView->setChecked((itemViewer->m_windowType == DvItemViewer::Browser &&
1855                          DvItemViewerPanel::ThumbnailView == BrowserView) ||
1856                         (itemViewer->m_windowType == DvItemViewer::Cast &&
1857                          DvItemViewerPanel::ThumbnailView == CastView));
1858   actions->addAction(thumbView);
1859   addAction(thumbView);
1860 
1861   QIcon listViewIcon = createQIcon("viewlist");
1862   QAction *listView  = new QAction(listViewIcon, tr("List View"), this);
1863   listView->setCheckable(true);
1864   listView->setIconText(tr("List"));
1865   listView->setChecked((itemViewer->m_windowType == DvItemViewer::Browser &&
1866                         DvItemViewerPanel::TableView == BrowserView) ||
1867                        (itemViewer->m_windowType == DvItemViewer::Cast &&
1868                         DvItemViewerPanel::TableView == CastView));
1869   actions->addAction(listView);
1870   addAction(listView);
1871 
1872   //	QIcon tableViewIcon = createQIconOnOffPNG("viewtable");
1873   //  QAction* tableView = new QAction(tableViewIcon, tr("Table View"), this);
1874   //  tableView->setCheckable(true);
1875   //  actions->addAction(tableView);
1876   //  addAction(tableView);
1877   addSeparator();
1878 
1879   // button to export file list to csv
1880   QAction *exportFileListAction = new QAction(tr("Export File List"), this);
1881   exportFileListAction->setIcon(createQIcon("export"));
1882   addAction(exportFileListAction);
1883 
1884   if (itemViewer->m_windowType == DvItemViewer::Browser &&
1885       !Preferences::instance()->isWatchFileSystemEnabled()) {
1886     addAction(CommandManager::instance()->getAction("MI_RefreshTree"));
1887     addSeparator();
1888   }
1889 
1890   connect(exportFileListAction, SIGNAL(triggered()), itemViewer->getPanel(),
1891           SLOT(exportFileList()));
1892 
1893   connect(folderUp, SIGNAL(triggered()), SIGNAL(folderUp()));
1894   connect(newFolder, SIGNAL(triggered()), SIGNAL(newFolder()));
1895   connect(thumbView, SIGNAL(triggered()), itemViewer->getPanel(),
1896           SLOT(setThumbnailsView()));
1897   connect(listView, SIGNAL(triggered()), itemViewer->getPanel(),
1898           SLOT(setTableView()));
1899   //	connect(listView      , SIGNAL(triggered()), itemViewer->getPanel(),
1900   // SLOT(setListView()));
1901   //	connect(tableView     , SIGNAL(triggered()), itemViewer->getPanel(),
1902   // SLOT(setTableView()));
1903 
1904   connect(m_folderBack, SIGNAL(triggered()), SIGNAL(folderBack()));
1905   connect(m_folderFwd, SIGNAL(triggered()), SIGNAL(folderFwd()));
1906 
1907   if (itemViewer->m_windowType == DvItemViewer::Browser) {
1908     connect(TApp::instance()->getCurrentScene(),
1909             SIGNAL(preferenceChanged(const QString &)), this,
1910             SLOT(onPreferenceChanged(const QString &)));
1911   }
1912 }
1913 
1914 //-----------------------------------------------------------------------------
1915 
onHistoryChanged(bool backEnable,bool fwdEnable)1916 void DvItemViewerButtonBar::onHistoryChanged(bool backEnable, bool fwdEnable) {
1917   if (backEnable)
1918     m_folderBack->setEnabled(true);
1919   else
1920     m_folderBack->setEnabled(false);
1921 
1922   if (fwdEnable)
1923     m_folderFwd->setEnabled(true);
1924   else
1925     m_folderFwd->setEnabled(false);
1926 }
1927 
1928 //-----------------------------------------------------------------------------
1929 
onPreferenceChanged(const QString & prefName)1930 void DvItemViewerButtonBar::onPreferenceChanged(const QString &prefName) {
1931   // react only when the related preference is changed
1932   if (prefName != "WatchFileSystem") return;
1933 
1934   QAction *refreshAct = CommandManager::instance()->getAction("MI_RefreshTree");
1935   if (Preferences::instance()->isWatchFileSystemEnabled()) {
1936     removeAction(refreshAct);
1937     removeAction(actions().last());  // remove separator
1938   } else {
1939     addAction(refreshAct);
1940     addSeparator();
1941   }
1942 }
1943