text: #include <QPainter>
  #include <QApplication>
  #include <QPixmap>
  
  #include "utils/utils.h"
  #include "utils/paint-utils.h"
  #include "utils/file-utils.h"
  #include "seafile-applet.h"
  #include "main-window.h"
  #include "rpc/rpc-client.h"
  #include "starred-files-list-model.h"
  #include "starred-file-item.h"
  #include "api/server-repo.h"
  
  #include "starred-file-item-delegate.h"
  
  namespace {
  
  /**
              name
     icon
              subtitle
   */
  
  const int kMarginLeft = 5;
  const int kMarginRight = 5;
  const int kMarginTop = 5;
  const int kMarginBottom = 5;
  const int kPadding = 5;
  
  const int kFileIconHeight = 36;
  const int kFileIconWidth = 36;
  const int kFileNameWidth = 210;
  const int kFileNameHeight = 30;
  
  const int kMarginBetweenFileIconAndName = 10;
  
  const char *kFileNameColor = "#3F3F3F";
  const char *kFileNameColorHighlighted = "#544D49";
  const char *kSubtitleColor = "#959595";
  const char *kSubtitleColorHighlighted = "#9D9B9A";
  const int kFileNameFontSize = 14;
  const int kSubtitleFontSize = 13;
  
  const char *kFileItemBackgroundColor = "white";
  const char *kFileItemBackgroundColorHighlighted = "#F9E0C7";
  
  const char *kItemBottomBorderColor = "#EEE";
  
  } // namespace
  
  StarredFileItemDelegate::StarredFileItemDelegate(QObject *parent)
    : QStyledItemDelegate(parent)
  {
  }
  
  QSize StarredFileItemDelegate::sizeHint(const QStyleOptionViewItem &option,
                                          const QModelIndex &index) const
  {
      StarredFileItem *item = getItem(index);
      if (!item) {
          return QStyledItemDelegate::sizeHint(option, index);
      }
  
      return sizeHintForItem(option, item);
  }
  
  QSize StarredFileItemDelegate::sizeHintForItem(const QStyleOptionViewItem &option,
                                                 const StarredFileItem *item) const
  {
      static const int width = kMarginLeft + kFileIconWidth
          + kMarginBetweenFileIconAndName + kFileNameWidth
          + kMarginRight + kPadding * 2;
  
      static const int height = kFileIconHeight + kPadding * 2 + kMarginTop + kMarginBottom;
  
      return QSize(width, height);
  }
  
  void StarredFileItemDelegate::paint(QPainter *painter,
                                      const QStyleOptionViewItem& option,
                                      const QModelIndex& index) const
  {
      StarredFileItem *item = getItem(index);
  
      paintItem(painter, option, item);
  }
  
  void StarredFileItemDelegate::paintItem(QPainter *painter,
                                          const QStyleOptionViewItem& option,
                                          const StarredFileItem *item) const
  {
      QBrush backBrush;
      bool selected = false;
      const StarredItem& file = item->file();
  
      if (option.state & (QStyle::State_HasFocus | QStyle::State_Selected)) {
          backBrush = QColor(kFileItemBackgroundColorHighlighted);
          selected = true;
  
      } else {
          backBrush = QColor(kFileItemBackgroundColor);
      }
  
      painter->save();
      painter->fillRect(option.rect, backBrush);
      painter->restore();
  
      // paint file icon
      QPixmap icon;
      switch (file.type) {
      case StarredItem::REPO:
          icon = QIcon(":/images/library-256.png").pixmap(36);
          break;
      case StarredItem::DIR:
          icon = QIcon(":/images/files/file_folder.png").pixmap(36);
          break;
      default: // server version lower 7.0.0 will execute the statement
          icon = getIconForFile(file.name());
          break;
      }
  
      QPoint file_icon_pos(kMarginLeft + kPadding, kMarginTop + kPadding);
      file_icon_pos += option.rect.topLeft();
      painter->save();
      painter->drawPixmap(file_icon_pos, icon);
      painter->restore();
  
      // Calculate the file column by the delta of mainwindow's width
      const int file_name_width = kFileNameWidth
        + seafApplet->mainWindow()->width() - seafApplet->mainWindow()->minimumWidth();
  
      // Paint file name
      painter->save();
      QPoint file_name_pos = file_icon_pos + QPoint(kFileIconWidth + kMarginBetweenFileIconAndName, 0);
      QRect file_name_rect(file_name_pos, QSize(file_name_width, kFileNameHeight));
      painter->setPen(QColor(selected ? kFileNameColorHighlighted : kFileNameColor));
      painter->setFont(changeFontSize(painter->font(), kFileNameFontSize));
  
      painter->drawText(file_name_rect,
                        Qt::AlignLeft | Qt::AlignTop,
                        fitTextToWidth(file.name(), option.font, file_name_width),
                        &file_name_rect);
      painter->restore();
  
      // Paint subtitle
      QString subtitle, size, mtime;
  
      size = readableFileSize(file.size);
      mtime = translateCommitTime(file.mtime);
  
      if (file.from_new_api) {
          subtitle = mtime;
      } else {
          subtitle = size + "  " + mtime;
      }
  
      painter->save();
      QPoint file_desc_pos = file_name_rect.bottomLeft() + QPoint(0, 5);
      QRect file_desc_rect(file_desc_pos, QSize(file_name_width, kFileNameHeight));
      painter->setFont(changeFontSize(painter->font(), kSubtitleFontSize));
      painter->setPen(QColor(selected ? kSubtitleColorHighlighted : kSubtitleColor));
      painter->drawText(file_desc_rect,
                        Qt::AlignLeft | Qt::AlignTop,
                        fitTextToWidth(subtitle, option.font, file_name_width),
                        &file_desc_rect);
      painter->restore();
  
      // Draw the bottom border lines
      painter->save();
      painter->setPen(QPen(QColor(kItemBottomBorderColor), 1, Qt::SolidLine));
      painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());
      painter->restore();
  }
  
  QPixmap StarredFileItemDelegate::getIconForFile(const QString& name) const
  {
      return QIcon(::getIconByFileName(name)).pixmap(QSize(kFileIconWidth, kFileIconHeight));
  }
  
  StarredFileItem* StarredFileItemDelegate::getItem(const QModelIndex &index) const
  {
      if (!index.isValid()) {
          return NULL;
      }
  
      const StarredFilesListModel *model = (const StarredFilesListModel*)index.model();
  
      return (StarredFileItem *)(model->itemFromIndex(index));
  }
  