summaryrefslogtreecommitdiff
path: root/src/ui/imageviewer.cpp
diff options
context:
space:
mode:
authorIru Cai <mytbk920423@gmail.com>2016-04-03 00:29:10 +0800
committerIru Cai <mytbk920423@gmail.com>2016-04-03 10:16:53 +0800
commit3a2cb75c85b8f98ebb0262ec3d5b590dcb9d79a1 (patch)
tree4d9ffee201e903f9ea2137327565d38395e4fd70 /src/ui/imageviewer.cpp
parentb91ee982b8ce1e08aad128a65312501ef5dd8ecd (diff)
downloadfqterm-3a2cb75c85b8f98ebb0262ec3d5b590dcb9d79a1.tar.xz
move imageviewer sources to ui/imageviewer
Diffstat (limited to 'src/ui/imageviewer.cpp')
-rw-r--r--src/ui/imageviewer.cpp1339
1 files changed, 0 insertions, 1339 deletions
diff --git a/src/ui/imageviewer.cpp b/src/ui/imageviewer.cpp
deleted file mode 100644
index 3292dd6..0000000
--- a/src/ui/imageviewer.cpp
+++ /dev/null
@@ -1,1339 +0,0 @@
-/***************************************************************************
- * fqterm, a terminal emulator for both BBS and *nix. *
- * Copyright (C) 2008 fqterm development group. *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
- ***************************************************************************/
-
-#include <QAction>
-#include <QBuffer>
-#include <QCursor>
-#include <QComboBox>
-#include <QDateTime>
-#include <QDataStream>
-#include <QDir>
-#include <QFile>
-#include <QFileInfo>
-#include <QIcon>
-#include <QKeyEvent>
-#include <QLineEdit>
-#include <QMessageBox>
-#include <QMouseEvent>
-#include <QMenu>
-#include <QMenuBar>
-#include <QPainter>
-#include <QPixmap>
-#include <QPushButton>
-#include <QSizeGrip>
-#include <QString>
-#include <QTextCodec>
-#include <QTimer>
-#include <QToolTip>
-#include <QTransform>
-#include <QTreeView>
-#include <QTextEdit>
-#include <QHeaderView>
-#include <QImageReader>
-
-#include "fqterm_canvas.h"
-#include "fqterm_config.h"
-#include "fqterm_exif_extractor.h"
-#include "fqterm_filedialog.h"
-#include "fqterm_path.h"
-#include "fqterm_trace.h"
-#include "imageviewer.h"
-
-namespace FQTerm {
-
- typedef enum {
- V_UNKNOWN = -1,
- V_ORIGINAL = 0,
- V_SHADOW,
- V_BESTFIT,
- V_ZOOMIN,
- V_ZOOMOUT,
- V_ROTLEFT,
- V_ROTRIGHT,
- V_FULLSCREEN
- } slideViewModes;
-
- typedef enum {
- SORT_UNSORTED = -1,
- SORT_LIKE,
- SORT_NEW,
- SORT_TRASH,
- SORT_RECOVER,
- SORT_TITLE
- } slideSortFlags;
-
-
- typedef enum {
- STAT_UNKNOWN = -1,
- STAT_LIKE,
- STAT_NEW,
- STAT_TRASH,
- STAT_RECOVER,
- STAT_TITLE,
- STAT_ALL
- } slideStatus;
-
- typedef enum {
- GEN_UNKNOWN = -1,
- GEN_CANCEL,
- GEN_NOCHANGE,
- GEN_RESHUFFLE,
- GEN_NOTAG,
- GEN_INTRASH,
- GEN_INTRASHES,
- GEN_TOSAVE,
- GEN_TOSAVES,
- GEN_TRASH,
- GEN_TRASHES,
- GEN_NOTRASH,
- GEN_RECOVER,
- GEN_RECOVERS,
- GEN_NORECOVER,
- GEN_SAVE,
- GEN_SAVES,
- GEN_DELETE,
- GEN_DELETES,
- GEN_SEARCHWRAP,
- GEN_SEARCHNOMATCH
- } generalStatus;
-
- static const char *fqloraTagStatus[] = {
- "Like",
- "New",
- "Trash",
- "Recover",
- "Title"
- };
-
- static const char *fqloraGeneralStatus[] = {
- "Canceled.",
- "No changes for ",
- "Reshuffled by ",
- "No tags by ",
- "item in the trash.",
- "items in the trash.",
- "item to save.",
- "items to save.",
- "image trashed.",
- "images trashed.",
- "Nothing to trash.",
- "image recovered.",
- "images recovered.",
- "Nothing to recover.",
- "image saved in ",
- "images saved in ",
- "image deleted.",
- "images deleted.",
- "Search wrapped.",
- "No matches."
- };
-
- static const int toolBarFixedHeight = 40;
- static const int statusBarFixedHeight = 18;
- static const QSize sortBoxFixedSize(110, 25);
-
- static const QString &iconPath(const QString &fileName) {
-
- static QString p = "";
-
- if (!fileName.isEmpty()) {
- p = getPath(RESOURCE) + ICON_SOURCE + fileName;
- }
-
- return p;
- }
-
- const QString &isPlural(const int num, const int status) {
-
- static QString m = "";
-
- if (num == 1) {
- return (m = fqloraGeneralStatus[status]);
- } else if (num > 1 && status > GEN_UNKNOWN && status < GEN_DELETES) {
- return (m = fqloraGeneralStatus[status + 1]);
- }
-
- return (m = fqloraGeneralStatus[GEN_UNKNOWN]);
- }
-
- // get user's desktop rectangle
- static const QRect &desktopSize() {
-
- static QRect size;
- QDesktopWidget myDesktop;
- return ((size = myDesktop.screenGeometry(myDesktop.primaryScreen())));
- }
-
- // FQTermImageFlow
- FQTermImageFlow::~FQTermImageFlow() {
-
- delete statusBar_;
- delete imageMenu_;
- delete imageFlow_;
-
- statusBar_ = NULL;
- imageMenu_ = NULL;
- imageFlow_ = NULL;
- }
-
- FQTermImageFlow::FQTermImageFlow(FQTermConfig * config, QWidget *parent,
- Qt::WindowFlags wflag) :
- FQTermImage(parent, wflag),
- imageFlow_(new ImageFlow(this)),
- imageMenu_(new ImageMenu(this)),
- statusBar_(new QStatusBar(this)),
- config_(config) {
-
- setWindowTitle(IMAGE_BROWSER_NAME);
- setAutoFillBackground(true);
- setBackgroundRole(QPalette::Midlight);
- setFixedSize(desktopSize().width() / 1.3, desktopSize().height() / 1.9);
-
- FQ_VERIFY(connect(this, SIGNAL(isTrashEmpty()), this, SLOT(checkTrashState())));
-
- // emblem state
- FQ_VERIFY(connect(imageFlow_, SIGNAL(emblemStatus(const int)), imageMenu_, SLOT(updateEmblems(const int))));
- FQ_VERIFY(connect(imageMenu_, SIGNAL(toggleFlowStatus(const int)), imageFlow_, SLOT(toggleStatus(const int))));
-
- // clear state
- FQ_VERIFY(connect(imageFlow_, SIGNAL(clearStatus(const bool)), imageMenu_, SLOT(updateClear(const bool))));
- FQ_VERIFY(connect(imageMenu_, SIGNAL(clearImages()), this, SLOT(clearImages())));
-
- // save state
- FQ_VERIFY(connect(imageFlow_, SIGNAL(saveStatus(const bool)), imageMenu_, SLOT(updateSave(const bool))));
- FQ_VERIFY(connect(imageMenu_, SIGNAL(saveImages()), this, SLOT(saveImages())));
-
- // trash state
- FQ_VERIFY(connect(this, SIGNAL(trashStatus(const bool)), imageMenu_, SLOT(updateDustbin(const bool))));
- FQ_VERIFY(connect(imageMenu_, SIGNAL(recoverImages()), this, SLOT(recoverImages())));
-
- // constructs a tool bar and its tool buttons
- QAction *closeBrowserAct = new QAction(QIcon(iconPath("window-close.png")), tr("Close"), this);
- closeBrowserAct->setShortcut(QKeySequence(Qt::Key_Q));
- FQ_VERIFY(connect(closeBrowserAct, SIGNAL(triggered()), this, SLOT(close())));
-
- QAction *trashAllAct = new QAction(QIcon(iconPath("trash-empty.png")), tr("Trash All"), this);
- trashAllAct->setShortcut(QKeySequence(Qt::Key_Delete));
- FQ_VERIFY(connect(trashAllAct, SIGNAL(triggered()), this, SLOT(trashAllImages())));
-
- QLabel *sortLabel = new QLabel(this);
- sortLabel->setMargin(5);
- sortLabel->setToolTip("Reshuffle images by tags");
- sortLabel->setPixmap(QPixmap(iconPath("edit-shuffle.png")));
-
- QComboBox *sortBox = new QComboBox(this);
- sortBox->setFocusPolicy(Qt::ClickFocus);
- sortBox->setFont(QFont("Serif", 12));
- sortBox->setFrame(false);
- sortBox->setFixedSize(sortBoxFixedSize);
- sortBox->insertItem(0, QIcon(iconPath("emblem-like-16x16.png")), tr("Like "));
- sortBox->insertItem(1, QIcon(iconPath("emblem-new-16x16.png")), tr("New "));
- sortBox->insertItem(2, QIcon(iconPath("emblem-trash-16x16.png")), tr("Trash "));
- sortBox->insertItem(3, QIcon(iconPath("emblem-recover-16x16.png")), tr("Recover "));
- sortBox->insertItem(4, QIcon(iconPath("emblem-title-16x16.png")), tr("Title "));
- FQ_VERIFY(connect(sortBox, SIGNAL(currentIndexChanged(int)), this, SLOT(reshuffleImages(int))));
-
- QToolBar *toolBar = new QToolBar(this);
- toolBar->setFixedHeight(toolBarFixedHeight);
- toolBar->setIconSize(QSize(32, 32));
- toolBar->addAction(closeBrowserAct);
- toolBar->addSeparator();
- toolBar->addWidget(sortLabel);
- toolBar->addWidget(sortBox);
- toolBar->addSeparator();
- toolBar->addAction(trashAllAct);
-
- // constructs a status bar to show instant messages
- statusBar_->setSizeGripEnabled(false);
- statusBar_->setFixedHeight(statusBarFixedHeight);
- statusBar_->setFont(QFont("Serif", 10, QFont::Bold));
- FQ_VERIFY(connect(imageFlow_, SIGNAL(statusMessage(const QString &)), this, SLOT(showStatusMessage(const QString &))));
- FQ_VERIFY(connect(this, SIGNAL(statusMessage(const QString &)), this, SLOT(showStatusMessage(const QString &))));
- // constructs a horizontal layout
- QVBoxLayout *vBox = new QVBoxLayout(this);
- vBox->setMargin(0);
- vBox->setSpacing(0);
- vBox->addWidget(toolBar);
- vBox->addWidget(imageFlow_);
- vBox->addWidget(imageMenu_);
- vBox->addWidget(statusBar_);
- vBox->setEnabled(true);
- setLayout(vBox);
- }
-
- const QString &FQTermImageFlow::poolSource(void) const {
-
- static QString p = "";
-
- p = config_->getItemValue("preference", "pool");
-
- if (p.isEmpty()) {
- p = getPath(USER_CONFIG) + POOL_SOURCE;
- }
-
- return p;
- }
-
- const QString &FQTermImageFlow::trashSource(void) const {
-
- static QString p = "";
-
- p = poolSource() + TRASH_SOURCE;
- return p;
- }
-
- // these three functions below are kept for
- // API compatibility.
- void FQTermImageFlow::adjustItemSize() {
-
- }
-
- void FQTermImageFlow::scrollTo(const QString &filePath) {
-
- }
-
- void FQTermImageFlow::updateImage(const QString &filePath) {
-
- }
-
- // slots and functions
- void FQTermImageFlow::loadImages(const int status) {
-
- int i;
- int itemStatus = (status == STAT_RECOVER) ? status : STAT_UNKNOWN;
- QString comment;
- QFileInfoList sourceList = sortedList(poolSource());
- QFileInfoList targetList = imageFlow_->digest(STAT_ALL);
-
- for (i = 0; i < sourceList.count(); i++) {
-
- if (!targetList.contains(sourceList[i])) {
-
- QImage image;
-
- if (!image.load(sourceList[i].absoluteFilePath())) {
- QFileIconProvider iconProvider;
- image = iconProvider.icon(sourceList[i]).pixmap(desktopSize().height() / 6.0).toImage();
- } else {
- image = image.scaled(desktopSize().width() / 6.0, desktopSize().height() / 6.0,
- Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
- }
-
- /* TODO */
- /* there should be a more flexible */
- /* method to deal with items' status */
- if (status == STAT_ALL) {
- itemStatus = STAT_NEW;
- }
-
- ImageFlowItem newItem(image, sourceList[i], comment,itemStatus);
- imageFlow_->add(newItem);
- }
- }
- }
-
- void FQTermImageFlow::reshuffleImages(const int status) {
-
- // there are images in the pool directory
- QList<qint64> itemKeys = imageFlow_->sort(status);
-
- if (imageFlow_->reorder(itemKeys)) {
- imageFlow_->setCurrentSlide(0);
- emit statusMessage(tr(fqloraGeneralStatus[GEN_RESHUFFLE]) + tr(fqloraTagStatus[status]));
- } else {
- emit statusMessage(tr(fqloraGeneralStatus[GEN_NOCHANGE]) + tr(fqloraTagStatus[status]));
- }
- }
-
- void FQTermImageFlow::saveImages() {
-
- QFileInfoList toSave = imageFlow_->digest(STAT_LIKE);
-
- if (!toSave.isEmpty()) {
-
- QMessageBox box;
- box.setWindowModality(Qt::NonModal);
- box.setWindowTitle("Information");
- box.setIconPixmap(QPixmap(iconPath("emblem-info.png")));
- box.setTextFormat(Qt::RichText);
- box.setText(QString("<b>%1</b> ").arg(toSave.count()) + isPlural(toSave.count(), GEN_TOSAVE));
- QPushButton *cancelButton = box.addButton(QMessageBox::Cancel);
- QPushButton *saveAllButton = box.addButton(QMessageBox::SaveAll);
- box.setDefaultButton(cancelButton);
- box.exec();
-
- if (box.clickedButton() == saveAllButton) {
-
- FQTermFileDialog fileDialog(config_);
- QString savePath =
- fileDialog.getExistingDirectory(tr("Save your likes under"), "*");
-
- if (savePath.isEmpty()) {
- emit statusMessage(tr(fqloraGeneralStatus[GEN_CANCEL]));
- return;
- }
-
- int i;
- for (i = 0; i < toSave.count(); i++) {
- QFile::rename(toSave[i].absoluteFilePath(), savePath + toSave[i].fileName());
- }
-
- imageFlow_->strip(STAT_LIKE);
- emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_SAVE) + savePath);
- } else {
- emit statusMessage(tr(fqloraGeneralStatus[GEN_CANCEL]));
- }
- } else {
- emit statusMessage(tr(fqloraGeneralStatus[GEN_NOTAG]) + tr(fqloraTagStatus[STAT_LIKE]));
- }
- }
-
- void FQTermImageFlow::checkTrashState() {
-
- QDir trashPath(trashSource());
-
- if (trashPath.count() <= 2) {
- emit trashStatus(false);
- } else {
- emit trashStatus(true);
- }
- }
-
- void FQTermImageFlow::clearImages() {
-
- int i;
- QString trashPath = trashSource();
- QDir trashDir(trashPath);
- QFileInfoList toRemove = imageFlow_->digest(STAT_TRASH);
-
- if (!trashDir.exists()) {
- trashDir.mkdir(trashPath);
- }
-
- if (!toRemove.isEmpty()) {
-
- for (i = 0; i < toRemove.count(); i++) {
- if (QFile::exists(toRemove[i].absoluteFilePath())) {
- QFile::rename(toRemove[i].absoluteFilePath(), trashPath + toRemove[i].fileName());
- }
- }
-
- imageFlow_->strip(STAT_TRASH);
- emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_TRASH));
- emit isTrashEmpty();
- } else {
- emit statusMessage(tr(fqloraGeneralStatus[GEN_NOTAG]) + tr(fqloraTagStatus[STAT_TRASH]));
- }
- }
-
- void FQTermImageFlow::trashAllImages() {
-
- int i;
- QString trashPath = trashSource();
- QDir trashDir(trashPath);
- QFileInfoList toRemove = imageFlow_->digest(STAT_ALL);
-
- if (!trashDir.exists()) {
- trashDir.mkdir(trashPath);
- }
-
- if (imageFlow_->count() > 0) {
- for (i = 0; i < imageFlow_->count(); i++) {
- if (QFile::exists(toRemove[i].absoluteFilePath())) {
- QFile::rename(toRemove[i].absoluteFilePath(), trashPath + toRemove[i].fileName());
- }
- }
-
- imageFlow_->clear();
- emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_TRASH));
- emit isTrashEmpty();
- } else {
- emit statusMessage(tr(fqloraGeneralStatus[GEN_NOTAG]) + tr(fqloraTagStatus[STAT_TRASH]));
- }
- }
-
- void FQTermImageFlow::recoverImages() {
-
- QString trashPath = trashSource();
- QDir trashDir(trashPath);
-
- if (!trashDir.exists()) {
- trashDir.mkdir(trashPath);
- } else if (trashDir.count() > 2) {
-
- int action = -1;;
- QFileInfoList toRecover = sortedList(trashPath);
-
- if (!toRecover.isEmpty()) {
-
- QMessageBox box;
- box.setWindowModality(Qt::NonModal);
- box.setWindowTitle("Take action");
- box.setIconPixmap(QPixmap(iconPath("emblem-info.png")));
- box.setTextFormat(Qt::RichText);
- box.setText(QString("<b>%1</b> ").arg(toRecover.count()) + isPlural(toRecover.count(), GEN_INTRASH));
- QPushButton *cancelButton = box.addButton(QMessageBox::Cancel);
- QPushButton *recoverButton = box.addButton(tr("Recover"), QMessageBox::ApplyRole);
- recoverButton->setIcon(QIcon(iconPath("button-recover.png")));
- QPushButton *deleteButton = box.addButton(tr("Delete"), QMessageBox::ApplyRole);
- deleteButton->setIcon(QIcon(iconPath("button-delete.png")));
- box.setDefaultButton(cancelButton);
- box.exec();
-
- if (box.clickedButton() == cancelButton) {
- emit statusMessage(tr(fqloraGeneralStatus[GEN_CANCEL]));
- return;
- } else if (box.clickedButton() == recoverButton) {
- action = 1;
- } else if (box.clickedButton() == deleteButton) {
- action = 0;
- }
-
- int i;
- QFile imageFile;
- QString poolPath = poolSource();
-
- for (i = 0; i < toRecover.count(); i++) {
- if (action == 1) {
- QFile::rename(toRecover[i].absoluteFilePath(), poolPath + toRecover[i].fileName());
- } else if (action == 0) {
- imageFile.setFileName(toRecover[i].absoluteFilePath());
- imageFile.remove();
- }
- }
-
- if (action == 1) {
- loadImages(STAT_RECOVER);
- emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_RECOVER));
- } else if (action == 0) {
- emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_DELETE));
- }
- }
- } else {
-
- emit statusMessage(tr(fqloraGeneralStatus[GEN_NORECOVER]));
- }
-
- emit isTrashEmpty();
- }
-
-
- void FQTermImageFlow::showStatusMessage(const QString &message) {
-
- if (statusBar_) {
- statusBar_->showMessage(message, 3000);
- }
- }
-
- QFileInfoList FQTermImageFlow::sortedList(const QString &path) {
-
- QDir sortPath(path);
-
- if (!sortPath.exists()) {
- sortPath.mkdir(path);
- }
-
- QStringList filters;
- QList<QByteArray> formats = QImageReader::supportedImageFormats();
- for (QList<QByteArray>::iterator it = formats.begin();
- it != formats.end();
- ++it) {
- QString filter("*.");
- filter.append(it->data());
- filters << filter;
- }
- sortPath.setNameFilters(filters);
-
- return (sortPath.entryInfoList(QDir::Files | QDir::Readable | QDir::NoSymLinks, QDir::Time));
- }
-
- // FQTermImageFlow events.
- void FQTermImageFlow::showEvent(QShowEvent *event) {
-
- emit isTrashEmpty();
-
- if (imageFlow_->count() <= 0) {
- loadImages(STAT_UNKNOWN);
- move((desktopSize().width() - width()) / 2.0, (desktopSize().height() - height()) / 2.0);
- } else {
- // TODO: insert new images
- loadImages(STAT_ALL);
- }
- }
-
- void FQTermImageFlow::closeEvent(QCloseEvent *event) {
-
- hide();
- }
-
- class ImageMenu::Private {
- public:
- int emblemStatus;
- bool dustbinStatus;
- bool saveStatus;
- bool clearStatus;
-
- QString tipMessage;
-
- QRect rectLike;
- QRect rectTrash;
- QRect rectNew;
- QRect rectRecover;
- QRect rectEmblems;
-
- QRect rectClear;
- QRect rectSave;
- QRect rectDustbin;
-
- QPixmap pixmapLike, pixmapLikeGray;
- QPixmap pixmapTrash, pixmapTrashGray;
- QPixmap pixmapNew, pixmapNewGray;
- QPixmap pixmapRecover, pixmapRecoverGray;
-
- QPixmap pixmapClear, pixmapClearGray;
- QPixmap pixmapSave, pixmapSaveGray;
- QPixmap pixmapDustbin, pixmapDustbinGray;
- };
-
- //ImageMenu
- ImageMenu::ImageMenu(QWidget *parent)
- : fh(new ImageMenu::Private) {
-
- setAutoFillBackground(true);
- setBackgroundRole(QPalette::Shadow);
- setFocusPolicy(Qt::NoFocus);
- setMouseTracking(true);
- setFixedHeight(60);
-
- fh->emblemStatus = -2;
- fh->dustbinStatus = false;
- fh->saveStatus = false;
- fh->clearStatus = false;
-
- fh->tipMessage = "";
-
- fh->rectLike = QRect(50, 14, 32, 32);
- fh->rectTrash = QRect(100, 14, 32, 32);
- fh->rectNew = QRect(150, 14, 32, 32);
- fh->rectRecover = QRect(200, 14, 32, 32);
- fh->rectEmblems = QRect(50, 14, 232, 32);
-
- fh->rectClear = QRect(300, 14, 32, 32);
- fh->rectSave = QRect(350, 14, 32, 32);
- fh->rectDustbin = QRect(400, 14, 32, 32);
-
- fh->pixmapLike = QPixmap(iconPath("emblem-like.png"));
- fh->pixmapLikeGray = QPixmap(iconPath("emblem-like-gray.png"));
-
- fh->pixmapTrash = QPixmap(iconPath("emblem-trash.png"));
- fh->pixmapTrashGray = QPixmap(iconPath("emblem-trash-gray.png"));
-
- fh->pixmapNew = QPixmap(iconPath("emblem-new.png"));
- fh->pixmapNewGray = QPixmap(iconPath("emblem-new-gray.png"));
-
- fh->pixmapRecover = QPixmap(iconPath("emblem-recover.png"));
- fh->pixmapRecoverGray = QPixmap(iconPath("emblem-recover-gray.png"));
-
- fh->pixmapClear = QPixmap(iconPath("clear-state.png"));
- fh->pixmapClearGray = QPixmap(iconPath("clear-state-gray.png"));
-
- fh->pixmapSave = QPixmap(iconPath("save-state.png"));
- fh->pixmapSaveGray = QPixmap(iconPath("save-state-gray.png"));
-
- fh->pixmapDustbin = QPixmap(iconPath("trash-state.png"));
- fh->pixmapDustbinGray = QPixmap(iconPath("trash-state-gray.png"));
- }
-
- ImageMenu::~ImageMenu() {
-
- delete fh;
- fh = NULL;
- }
-
- void ImageMenu::updateEmblems(const int status) {
-
- if (fh->emblemStatus != status) {
- update(fh->rectEmblems);
- }
-
- fh->emblemStatus = status;
- }
-
- void ImageMenu::updateClear(const bool hasOrNot) {
-
- if (fh->clearStatus != hasOrNot) {
- update(fh->rectClear);
- }
-
- fh->clearStatus = hasOrNot;
- }
-
- void ImageMenu::updateSave(const bool hasOrNot) {
-
- if (fh->saveStatus != hasOrNot) {
- update(fh->rectSave);
- }
-
- fh->saveStatus = hasOrNot;
- }
-
- void ImageMenu::updateDustbin(const bool fullOrNot) {
-
- if (fh->dustbinStatus != fullOrNot) {
- update(fh->rectDustbin);
- }
-
- fh->dustbinStatus = fullOrNot;
- }
-
- void ImageMenu::paintEvent(QPaintEvent *event) {
-
- QPainter p(this);
-
- p.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing);
-
- if (fh->emblemStatus == STAT_LIKE) {
- p.drawPixmap(fh->rectLike, fh->pixmapLike);
- } else {
- p.drawPixmap(fh->rectLike, fh->pixmapLikeGray);
- }
-
- if (fh->emblemStatus == STAT_TRASH) {
- p.drawPixmap(fh->rectTrash, fh->pixmapTrash);
- } else {
- p.drawPixmap(fh->rectTrash, fh->pixmapTrashGray);
- }
-
- if (fh->emblemStatus == STAT_NEW) {
- p.drawPixmap(fh->rectNew, fh->pixmapNew);
- } else {
- p.drawPixmap(fh->rectNew, fh->pixmapNewGray);
- }
-
- if (fh->emblemStatus == STAT_RECOVER) {
- p.drawPixmap(fh->rectRecover, fh->pixmapRecover);
- } else {
- p.drawPixmap(fh->rectRecover, fh->pixmapRecoverGray);
- }
-
- if (fh->clearStatus == true) {
- p.drawPixmap(fh->rectClear, fh->pixmapClear);
- } else {
- p.drawPixmap(fh->rectClear, fh->pixmapClearGray);
- }
-
- if (fh->saveStatus == true) {
- p.drawPixmap(fh->rectSave, fh->pixmapSave);
- } else {
- p.drawPixmap(fh->rectSave, fh->pixmapSaveGray);
- }
-
- if (fh->dustbinStatus == true) {
- p.drawPixmap(fh->rectDustbin, fh->pixmapDustbin);
- } else {
- p.drawPixmap(fh->rectDustbin, fh->pixmapDustbinGray);
- }
-
- p.end();
- }
-
- void ImageMenu::mouseReleaseEvent(QMouseEvent *event) {
-
- if (event->button() == Qt::LeftButton
- || event->button() == Qt::RightButton) {
-
- if (fh->rectLike.contains(event->pos())) {
- emit toggleFlowStatus(STAT_LIKE);
- }
-
- if (fh->rectTrash.contains(event->pos())) {
- emit toggleFlowStatus(STAT_TRASH);
- }
-
- if (fh->rectClear.contains(event->pos())) {
- emit clearImages();
- }
-
- if (fh->rectSave.contains(event->pos())) {
- emit saveImages();
- }
-
- if (fh->rectDustbin.contains(event->pos())) {
- emit recoverImages();
- }
- }
- }
-
- // ImageFlow: this subclasses PictureFlow
- class ImageFlow::Private {
- public:
- int emblemStatus;
- int likeCount;
- int clearCount;
-
- QList<QByteArray> itemsTitles;
- QHash<QByteArray, qint64> itemsTitleKeyPairs;
- QList<ImageFlowItem> items;
- };
-
- ImageFlow::~ImageFlow() {
-
- delete m;
- m = NULL;
- }
-
- // construct an emptry pictureflow.
- ImageFlow::ImageFlow(QWidget *parent)
- : PictureFlow(parent), m(new ImageFlow::Private) {
-
- // initial setup
- setFocusPolicy(Qt::StrongFocus);
- setZoomFactor(120);
- setSlideCount(0);
- m->emblemStatus = -1;
- m->likeCount = 0;
- m->clearCount = 0;
- }
-
- const ImageFlowItem& ImageFlow::operator[](int index) const {
-
- return (m->items[index]);
- }
-
- ImageFlowItem& ImageFlow::operator[](int index) {
-
- return (m->items[index]);
- }
-
- const ImageFlowItem& ImageFlow::at(int index) const {
-
- return (m->items[index]);
- }
-
- void ImageFlow::add(const ImageFlowItem &item) {
-
- QByteArray title = item.info().fileName().toLocal8Bit();
-
- m->items.append(item);
- m->itemsTitles.append(title);
- m->itemsTitleKeyPairs.insert(title, item.key());
-
- // set the status pixmap
- int index = m->items.indexOf(item);
- m->items[index].setStatus(item.status());
-
- int count = m->items.count();
- setSlideCount(count);
- setSlide(count - 1, item.image());
- }
-
- QList<QByteArray>& ImageFlow::itemsTitles() const {
-
- return (m->itemsTitles);
- }
-
- void ImageFlow::clear() {
-
- m->items.clear();
- setSlideCount(0);
- setCurrentSlide(0);
- PictureFlow::clear();
- }
-
- int ImageFlow::count() const {
-
- return (m->items.count());
- }
-
- int ImageFlow::size() const {
-
- return (m->items.size());
- }
-
- QFileInfoList& ImageFlow::digest(const int status) {
-
- int i;
- int count = m->items.size();
- static QFileInfoList result;
-
- result.clear();
-
- for (i = 0; i < count; i++) {
- switch (status) {
- case STAT_ALL:
- result.append(m->items[i].info());
- break;
- default:
- if (m->items[i].status() == status) {
- result.append(m->items[i].info());
- }
- break;
- }
- }
-
- return result;
- }
-
- void ImageFlow::strip(const int status) {
-
- int i;
- int count = m->items.count();
- QList<int> dirtyIndexes;
-
- // We cannot delete items in a loop because
- // items count will change while deleting.
- // A better method is to use another list
- // to record 'dirty' items, and by looping this
- // dirty list, we can correctly delete those
- // dirty items successfully.
- for (i = 0; i < count; i++) {
- if (m->items[i].status() == status) {
- dirtyIndexes.append(i);
- }
- }
-
- if (!dirtyIndexes.isEmpty()) {
-
- for (i = 0; i < dirtyIndexes.count(); i++) {
- // Note: dirtyIndexes[i] - i: the actual
- // position of the dirty item.
- m->items.removeAt(dirtyIndexes[i] - i);
- }
-
- dirtyIndexes.clear();
- reorder(sort(STAT_ALL));
-
- for (i = 0; i < m->items.count(); i++) {
- setSlide(i, m->items[i].image());
- }
-
- setSlideCount(i);
- setCurrentSlide(0);
-
- switch(status) {
- case STAT_LIKE:
- m->likeCount = 0;
- emit saveStatus(false);
- emit emblemStatus(STAT_UNKNOWN);
- break;
- case STAT_TRASH:
- m->clearCount = 0;
- emit clearStatus(false);
- emit emblemStatus(STAT_UNKNOWN);
- break;
- default:
- break;
- }
- }
- }
-
- QList<qint64> ImageFlow::sort(const int status) {
-
- int i;
- int count = m->items.count();
- QList<qint64> itemKeys;
-
- switch (status) {
- case STAT_TITLE:
- qStableSort(m->itemsTitles.begin(), m->itemsTitles.end(), qLess<QByteArray>());
- for (i = 0; i < m->itemsTitles.count(); i++) {
- itemKeys.append(m->itemsTitleKeyPairs.value(m->itemsTitles[i]));
- }
- break;
- default:
- for (i = 0; i < count; i++) {
- if (m->items[i].status() == status) {
- itemKeys.prepend(m->items[i].key());
- } else {
- itemKeys.append(m->items[i].key());
- }
- }
- break;
- }
-
- // this might be unnecessary here.
- return itemKeys;
- }
-
- bool ImageFlow::reorder(const QList<qint64>& itemsKey) {
-
- int items_count = m->items.size();
-
- if (itemsKey.size() != items_count) {
-
- return (false);
- }
-
- // Collect Items Key
- QList<qint64> currentItemsKey;
- for (int i = 0; i < items_count; i++) {
-
- currentItemsKey.append(m->items.at(i).key());
- }
-
- if (currentItemsKey == itemsKey) {
- // if identical, we don't sort.
- return (false);
- }
-
- // Swap Items
- for (int i=0; i < items_count; i++) {
-
- int index = currentItemsKey.indexOf(itemsKey.at(i));
- if (i == index) {
- continue;
- }
-
- QImage imgA = m->items[i].image();
- QImage imgB = m->items[index].image();
-
- setSlide(index, imgA);
- setSlide(i, imgB);
-
- m->items.swap(i, index);
- currentItemsKey.swap(i, index);
- }
-
- update();
- rehash();
- return(true);
- }
-
- void ImageFlow::rehash(void) {
-
- int count = m->items.count();
-
- if (count <= 0) {
- return;
- }
-
- int i;
-
- m->itemsTitles.clear();
- m->itemsTitleKeyPairs.clear();
-
- qint64 k;
- QByteArray b;
-
- for (i = 0; i < count; i++) {
- k = m->items[i].key();
- b = m->items[i].info().fileName().toLocal8Bit();
- m->itemsTitles.append(b);
- m->itemsTitleKeyPairs.insert(b, k);
- }
- }
-
- void ImageFlow::toggleStatus(const int status) {
-
- int index = currentSlide();
- int count = m->items.count();
-
- if (index >= 0 && index < count) {
-
- setUpdatesEnabled(false);
- if (m->items[index].status() != status) {
-
- switch (status) {
- case STAT_LIKE:
- m->likeCount++;
- if (m->items[index].status() == STAT_TRASH) {
- m->clearCount--;
- }
- emit saveStatus(true);
- break;
- case STAT_TRASH:
- m->clearCount++;
- if (m->items[index].status() == STAT_LIKE) {
- m->likeCount--;
- }
- emit clearStatus(true);
- break;
- default:
- break;
- }
-
- m->items[index].setStatus(status);
- emit statusMessage(tr("Tagged as ") + tr(fqloraTagStatus[status]));
-
- } else {
-
- switch (status) {
- case STAT_LIKE:
- m->likeCount--;
- break;
- case STAT_TRASH:
- m->clearCount--;
- break;
- default:
- break;
- }
-
- m->items[index].setStatus(STAT_UNKNOWN);
- emit statusMessage("Tag cleared");
- }
-
- if (m->likeCount <= 0) {
- emit saveStatus(false);
- } else {
- emit saveStatus(true);
- }
-
- if (m->clearCount <= 0) {
- emit clearStatus(false);
- } else {
- emit clearStatus(true);
- }
-
- setUpdatesEnabled(true);
- }
- }
-
- void ImageFlow::setCurrentImage(const int index) {
-
- int count = size();
-
- if (count > 0 && index > 0 && index < count) {
-
- setCurrentSlide(index);
- }
- }
-
-// events
- void ImageFlow::paintEvent(QPaintEvent *event) {
-
- PictureFlow::paintEvent(event);
-
- if (slideCount() < 1) {
- return;
- }
-
- QPainter p(this);
-
- // White Pen for File Info
- p.setPen(Qt::gray);
-
- int cw = width() / 2;
- int wh = height();
-
- ImageFlowItem& item = m->items[currentSlide()];
-
- // Draw File Name if it's not empty
- QString title = item.info().fileName();
- if (!title.isEmpty()) {
-
- p.setFont(QFont(p.font().family(), p.font().pointSize() + 1, QFont::Bold));
- p.drawText(cw - (QFontMetrics(p.font()).width(title) / 2), wh - 20, title);
- }
-
- p.end();
-
- if (m->emblemStatus != item.status()) {
- emit emblemStatus(item.status());
- }
-
- m->emblemStatus = item.status();
- }
-
- // ImageFlowItem
- class ImageFlowItem::Private {
- public:
- QString filePath;
- QFileInfo info;
- QString comment;
- QImage image;
- int status;
- qint64 key;
-
- };
-
- ImageFlowItem::~ImageFlowItem() {
-
- delete m;
- m = NULL;
- }
-
- // constructs an empty item
- ImageFlowItem::ImageFlowItem(QObject *parent)
- : QObject(parent), m(new ImageFlowItem::Private) {
-
- m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
- }
-
- ImageFlowItem::ImageFlowItem(const ImageFlowItem &item)
- : QObject(item.parent()), m(new ImageFlowItem::Private) {
-
- operator=(item);
- }
-
- // constructs an item with a given image
- ImageFlowItem::ImageFlowItem(const QImage &image, QObject *parent)
- : QObject(parent), m(new ImageFlowItem::Private) {
-
- m->image = image;
- m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
- }
-
- // constructs an image with given image and title
- ImageFlowItem::ImageFlowItem(const QImage &image, const QFileInfo &info, QObject *parent)
- : QObject(parent), m(new ImageFlowItem::Private) {
-
- m->image = image;
- m->info = info;
- m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
- }
-
- // constructs an image with given image, title and comment
- ImageFlowItem::ImageFlowItem(const QImage &image, const QFileInfo &info, const QString &comment, QObject *parent)
- : QObject(parent), m(new ImageFlowItem::Private) {
-
- m->image = image;
- m->info = info;
- m->comment = comment;
- m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
- }
-
- // constructs an image with given image, title, type, size, time and state
- ImageFlowItem::ImageFlowItem(const QImage &image, const QFileInfo &info, const QString& comment, const int status, QObject *parent)
- : QObject(parent), m(new ImageFlowItem::Private) {
-
- m->image = image;
- m->info = info;
- m->comment = comment;
- m->status = status;
-
- m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
- }
-
- // funcs and slots
- ImageFlowItem& ImageFlowItem::operator=(const ImageFlowItem &item) {
-
- m->info = item.m->info;
- m->comment = item.m->comment;
- m->key = item.m->key;
-
- if (item.m->filePath.isEmpty()) {
- m->image = item.m->image;
- } else {
- setImage(item.m->filePath, m->key);
- }
-
- return (*this);
- }
-
- bool ImageFlowItem::operator==(const ImageFlowItem& item) const {
-
- return (item.m->key == m->key);
- }
-
- bool ImageFlowItem::operator!=(const ImageFlowItem& item) const {
-
- return (item.m->key != m->key);
- }
-
- const QString& ImageFlowItem::comment() const {
-
- return (m->comment);
- }
-
- const QImage& ImageFlowItem::image() const {
-
- return (m->image);
- }
-
- int ImageFlowItem::status(void) const {
-
- return (m->status);
- }
-
- const QFileInfo& ImageFlowItem::info(void) const {
-
- return (m->info);
- }
-
- qint64 ImageFlowItem::key() const {
-
- return (m->key);
- }
-
- void ImageFlowItem::setInfo(const QFileInfo& info) {
-
- m->info = info;
- m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
- }
-
- void ImageFlowItem::setComment(const QString &comment) {
-
- m->comment = comment;
- m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
- }
-
- void ImageFlowItem::setImage(const QImage &image) {
-
- m->image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
- }
-
- void ImageFlowItem::setImage(const QString &filePath, int size) {
-
- m->filePath = filePath;
- m->key = size;
-
- QTimer::singleShot(1000, this, SLOT(loadImage()));
- }
-
- void ImageFlowItem::setStatus(const int status) {
-
- m->status = status;
- }
-
- void ImageFlowItem::loadImage() {
-
- int imageHeight = m->key;
-
- if (!m->image.load(m->filePath)) {
- QFileIconProvider iconProvider;
- m->image = iconProvider.icon(QFileInfo(m->filePath)).pixmap(imageHeight).toImage();
- } else {
- m->image = resizeImage(m->image, imageHeight);
- }
-
- m->filePath.clear();
- m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment);
- }
-
- QImage ImageFlowItem::resizeImage(const QImage &image, int size) {
-
- if (size == image.width() && size == image.height()) {
- return image;
- }
-
- double scaleWidth = size / (double)image.width();
- double scaleHeight = size / (double)image.height();
- double smaller = qMin(scaleWidth, scaleHeight);
-
- int w = (int) qRound(smaller * image.width());
- int h = (int) qRound(smaller * image.height());
-
- return (image.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
- }
-
-} // namespace FQTerm
-
-#include "imageviewer.moc"