summaryrefslogtreecommitdiff
path: root/src/ui/imageviewer/fqterm_canvas.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/imageviewer/fqterm_canvas.cpp')
-rw-r--r--src/ui/imageviewer/fqterm_canvas.cpp537
1 files changed, 537 insertions, 0 deletions
diff --git a/src/ui/imageviewer/fqterm_canvas.cpp b/src/ui/imageviewer/fqterm_canvas.cpp
new file mode 100644
index 0000000..82fc971
--- /dev/null
+++ b/src/ui/imageviewer/fqterm_canvas.cpp
@@ -0,0 +1,537 @@
+/***************************************************************************
+ * 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 <QCloseEvent>
+#include <QKeyEvent>
+#include <QResizeEvent>
+#include <QMouseEvent>
+#include <QMenu>
+#include <QMenuBar>
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QLabel>
+#include <QMatrix>
+#include <QToolBar>
+#include <QActionGroup>
+#include <QToolButton>
+#include <QDesktopServices>
+#include <QDir>
+#include <QUrl>
+#include <QImageReader>
+#include <QMovie>
+
+#include "fqterm_canvas.h"
+#include "fqterm.h"
+#include "fqterm_config.h"
+#include "fqterm_path.h"
+#include "fqterm_filedialog.h"
+
+namespace FQTerm {
+
+FQTermCanvas::FQTermCanvas(FQTermConfig * config, QWidget *parent, Qt::WindowFlags f)
+ : QScrollArea(parent),
+ adjustMode_(Fit),
+ aspectRatioMode_(Qt::KeepAspectRatio){
+ // TODO: dirty trick
+
+ if (f == 0) {
+ isEmbedded = true;
+ } else {
+ isEmbedded = false;
+ }
+
+ config_ = config;
+
+ menu_ = new QMenu(parent);
+ menu_->addAction(tr("zoom 1:1"), this, SLOT(oriSize()), tr("Ctrl+Z"));
+ menu_->addAction(tr("adjust size"), this, SLOT(autoAdjust()), tr("Ctrl+X"));
+ menu_->addSeparator();
+ QAction* zoomInAction = menu_->addAction(tr("zoom in"), this,
+ SLOT(zoomIn()), tr("Ctrl+="));
+ QAction* zoomOutAction = menu_->addAction(tr("zoom out"), this,
+ SLOT(zoomOut()), tr("Ctrl+-"));
+ if (!isEmbedded) {
+ menu_->addAction(tr("fullscreen"), this, SLOT(fullScreen()), tr("Ctrl+F"));
+ }
+ menu_->addSeparator();
+ menu_->addAction(tr("rotate CW 90"), this, SLOT(cwRotate()),
+ tr("Ctrl+]"));
+ menu_->addAction(tr("rotate CCW 90"), this, SLOT(ccwRotate()),
+ tr("Ctrl+["));
+ menu_->addSeparator();
+ gifPlayAction_ = menu_->addAction(tr("play gif"), this,
+ SLOT(playGIF()), tr("Ctrl+/"));
+ menu_->addSeparator();
+ menu_->addAction(tr("save as"), this, SLOT(saveImage()), tr("Ctrl+S"));
+ menu_->addAction(tr("copy to"), this, SLOT(copyImage()), tr("Ctrl+C"));
+ menu_->addAction(tr("silent copy"), this, SLOT(silentCopy()),
+ tr("Shift+S"));
+
+ if (!isEmbedded) {
+ menu_->addAction(tr("delete"), this, SLOT(deleteImage()), tr("Ctrl+D"));
+
+ menu_->addSeparator();
+ menu_->addAction(tr("exit"), this, SLOT(close()), tr("Ctrl+Q"));
+ }
+
+ toolBar_ = new QToolBar(this);
+
+ toolBar_->addAction(QIcon(getPath(RESOURCE) + "pic/ViewerButtons/open.png"),
+ tr("Open Dir"), this, SLOT(openDir()));
+
+ zoomInAction->setIcon(
+ QIcon(getPath(RESOURCE) + "pic/ViewerButtons/zoomin.png"));
+ zoomOutAction->setIcon(
+ QIcon(getPath(RESOURCE) + "pic/ViewerButtons/zoomout.png"));
+
+ toolBar_->addAction(zoomInAction);
+ toolBar_->addAction(zoomOutAction);
+
+ QActionGroup* gifGroup = new QActionGroup(this);
+ gifPlayAction_->setIcon(
+ QIcon(getPath(RESOURCE) + "pic/ViewerButtons/play_gif.png"));
+ toolBar_->addAction(gifPlayAction_);
+
+ QActionGroup* showSettingGroup = new QActionGroup(this);
+ QMenu* showSettingMenu = new QMenu(this);
+
+ QAction* showSettingFitAction =
+ showSettingMenu->addAction(tr("show Fit"), this, SLOT(SetAdjustMode()));
+ showSettingFitAction->setCheckable(true);
+ showSettingFitAction->setData(Fit);
+ showSettingGroup->addAction(showSettingFitAction);
+
+ QAction* showSettingMaxFitAction =
+ showSettingMenu->addAction(tr("show MaxFit"),
+ this, SLOT(SetAdjustMode()));
+ showSettingMaxFitAction->setCheckable(true);
+ showSettingMaxFitAction->setData(MaxFit);
+ showSettingGroup->addAction(showSettingMaxFitAction);
+
+ QAction* showSettingOriginAction =
+ showSettingMenu->addAction(tr("show Origin"),
+ this, SLOT(SetAdjustMode()));
+ showSettingOriginAction->setCheckable(true);
+ showSettingOriginAction->setData(Origin);
+ showSettingGroup->addAction(showSettingOriginAction);
+
+ QAction* showSettingStrechAction =
+ showSettingMenu->addAction(tr("show Stretch"),
+ this, SLOT(SetAdjustMode()));
+ showSettingStrechAction->setCheckable(true);
+ showSettingStrechAction->setData(Stretch);
+ showSettingGroup->addAction(showSettingStrechAction);
+
+ QToolButton* showSettingButton = new QToolButton(this);
+ QAction* dummyAction = new QAction(
+ QIcon(getPath(RESOURCE) + "pic/ViewerButtons/adjustsize.png"),
+ tr("Adjust Mode"), showSettingButton);
+ showSettingButton->setDefaultAction(dummyAction);
+ showSettingButton->setMenu(showSettingMenu);
+ showSettingButton->setPopupMode(QToolButton::InstantPopup);
+
+ showSettingFitAction->setChecked(true);
+
+ toolBar_->addWidget(showSettingButton);
+
+
+
+#if QT_VERSION >= 0x040200
+ setAlignment(Qt::AlignCenter);
+#endif
+ label_ = new QLabel(viewport());
+ label_->setScaledContents(true);
+ label_->setAlignment(Qt::AlignCenter);
+ label_->setText(tr("No Preview Available"));
+ setWidget(label_);
+ // resize(200, 100);
+}
+
+FQTermCanvas::~FQTermCanvas() {
+ //delete label;
+ //delete m_pMenu;
+}
+
+void FQTermCanvas::oriSize() {
+ useAdjustMode_ = false;
+ imageSize_ = image_.size();
+ adjustSize(size());
+}
+
+void FQTermCanvas::zoomIn() {
+ useAdjustMode_ = false;
+ resizeImage(0.05f);
+}
+
+void FQTermCanvas::zoomOut() {
+ useAdjustMode_ = false;
+ resizeImage(-0.05f);
+}
+
+void FQTermCanvas::autoAdjust() {
+ useAdjustMode_ = true;
+ adjustSize(size());
+}
+
+void FQTermCanvas::cwRotate() {
+ rotateImage(90);
+}
+
+void FQTermCanvas::ccwRotate() {
+ rotateImage(-90);
+}
+
+void FQTermCanvas::fullScreen() {
+ if (!isFullScreen()) {
+ showFullScreen();
+ } else {
+ showNormal();
+ }
+}
+
+void FQTermCanvas::loadImage(const QString& name, bool performAdjust) {
+ if (label_->movie()) {
+ label_->movie()->stop();
+ label_->setMovie(NULL);
+ }
+
+ gifPlayAction_->setEnabled(name.endsWith("gif"));
+
+
+ bool res = image_.load(name);
+ if (!res) {
+ QList<QByteArray> formats = QImageReader::supportedImageFormats();
+ for (QList<QByteArray>::iterator it = formats.begin();
+ !res && it != formats.end();
+ ++it) {
+ res = image_.load(name, it->data());
+ }
+ }
+ if (!image_.isNull()) {
+ fileName_ = QFileInfo(name).absoluteFilePath();
+ setWindowTitle(QFileInfo(name).fileName());
+
+ useAdjustMode_ = true;
+
+ if (!isEmbedded) {
+ QSize szView(image_.size());
+ szView.scale(640, 480, aspectRatioMode_);
+
+ if (szView.width() < image_.width()) {
+ imageSize_ = szView;
+ label_->resize(imageSize_);
+ label_->clear();
+ label_->setAlignment(Qt::AlignCenter);
+ label_->setPixmap(scaleImage(imageSize_));
+
+ if (!isEmbedded) {
+ resize(szView *1.1);
+ }
+ } else {
+ imageSize_ = image_.size();
+ label_->resize(imageSize_);
+ label_->setPixmap(QPixmap::fromImage(image_));
+ if (!isEmbedded) {
+ resize(imageSize_ + QSize(5, 5));
+ }
+ }
+ }
+ if (isEmbedded) {
+ label_->hide();
+ if (performAdjust) autoAdjust();
+ else label_->setPixmap(QPixmap::fromImage(image_));
+
+ label_->show();
+ }
+
+ } else {
+ FQ_TRACE("canvas", 1) << "Can't load the image: " << name;
+ }
+}
+
+void FQTermCanvas::playGIF() {
+ if (fileName_.endsWith("gif")) {
+ gifPlayer_.setFileName(fileName_);
+ if (gifPlayer_.isValid()) {
+ label_->setMovie(&gifPlayer_);
+ gifPlayer_.stop();
+ gifPlayer_.start();
+ return;
+ }
+ }
+}
+
+void FQTermCanvas::resizeImage(float ratio) {
+ QSize szImg = imageSize_;
+ szImg *= (1+ratio);
+ //we dont need so big
+ if (szImg.width() > 10000 || szImg.height() > 10000 ||
+ szImg.width() < 1 || szImg.height() < 1) {
+ return ;
+ }
+ imageSize_ = szImg;
+
+ if (!isFullScreen() && !isEmbedded) {
+ resize(imageSize_ *1.1);
+ } else {
+ adjustSize(size());
+ }
+}
+
+void FQTermCanvas::rotateImage(float ang) {
+ QMatrix wm;
+
+ wm.rotate(ang);
+
+ image_ = image_.transformed(wm, Qt::SmoothTransformation);
+
+ imageSize_ = image_.size();
+
+ adjustSize(size());
+}
+
+void FQTermCanvas::copyImage() {
+ QFileInfo fi(fileName_);
+// QString strSave =
+// QFileDialog::getSaveFileName(
+// this,tr("Choose a filename to save under"),
+// QDir::currentPath() + fi.fileName());
+ FQTermFileDialog fileDialog(config_);
+ QString strSave = fileDialog.getSaveName(fi.fileName(), "");
+ if (strSave.isEmpty()) {
+ return ;
+ }
+ QFile file(fileName_);
+ if (file.open(QIODevice::ReadOnly)) {
+ QFile save(strSave);
+ if (save.open(QIODevice::WriteOnly)) {
+ QByteArray ba = file.readAll();
+ QDataStream ds(&save);
+ ds.writeRawData(ba, ba.size());
+ save.close();
+ }
+ file.close();
+ }
+}
+
+void FQTermCanvas::silentCopy() {
+ // save it to $savefiledialog
+ QString strPath = config_->getItemValue("global", "savefiledialog");
+
+ QFileInfo fi(fileName_);
+ QString strSave = strPath + "/" + fi.fileName();
+
+ fi.setFile(strSave);
+
+ // add (%d) if exist
+ int i = 1;
+ while (fi.exists()) {
+ strSave = QString("%1/%2(%3).%4").arg(fi.dir().path()).arg
+ (fi.completeBaseName()).arg(i).arg(fi.suffix());
+ fi.setFile(strSave);
+ }
+
+ // copy it
+ QFile file(fileName_);
+ if (file.open(QIODevice::ReadOnly)) {
+ QFile save(strSave);
+ if (save.open(QIODevice::WriteOnly)) {
+ QByteArray ba = file.readAll();
+ QDataStream ds(&save);
+ ds.writeRawData(ba, ba.size());
+ save.close();
+ }
+ file.close();
+ }
+}
+
+QPixmap FQTermCanvas::scaleImage(const QSize &sz) {
+ return QPixmap::fromImage(
+ image_.scaled(sz, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+}
+
+void FQTermCanvas::moveImage(float dx, float dy) {
+ scrollContentsBy(int(widget()->width()*dx), int(widget()->height() *dy));
+}
+
+void FQTermCanvas::saveImage() {
+
+ QFileInfo fi(fileName_);
+ FQTermFileDialog fileDialog(config_);
+ QString strSave = fileDialog.getSaveName(fi.fileName(), "");
+ if (strSave.isEmpty()) {
+ return ;
+ }
+ QString fmt = fi.suffix().toUpper();
+ if (!image_.save(strSave, fmt.toLatin1())) {
+ QMessageBox::warning(this, tr("Failed to save file"),
+ tr("Cant save file, maybe format not supported"));
+ }
+}
+
+void FQTermCanvas::deleteImage() {
+ QFile::remove(fileName_);
+ close();
+}
+
+void FQTermCanvas::closeEvent(QCloseEvent *ce) {
+ if (!isEmbedded) {
+ delete this;
+ }
+}
+
+void FQTermCanvas::viewportResizeEvent(QResizeEvent *re) {
+ adjustSize(re->size());
+}
+
+void FQTermCanvas::mousePressEvent(QMouseEvent *me) {
+ /* remove this to avoid click by mistake
+ if(me->button()&LeftButton)
+ {
+ close();
+ return;
+ }
+ */
+ if (me->button() &Qt::RightButton) {
+ menu_->popup(me->globalPos());
+ }
+}
+
+void FQTermCanvas::keyPressEvent(QKeyEvent *ke) {
+ switch (ke->key()) {
+ case Qt::Key_Escape:
+ if (!isEmbedded) {
+ if (isFullScreen()) {
+ showNormal();
+ } else {
+ close();
+ }
+ }
+
+ break;
+ case Qt::Key_D:
+ if (!isEmbedded){
+ deleteImage();
+ }
+ break;
+ case Qt::Key_Q:
+ if (!isEmbedded){
+ close();
+ }
+ break;
+ }
+}
+
+void FQTermCanvas::adjustSize(QSize szView) {
+ szView -= QSize(2 * frameWidth(), 2 * frameWidth());
+ if (label_->pixmap() == NULL && image_.isNull()) {
+ label_->resize(szView);
+ return ;
+ }
+
+ QSize szImg = imageSize_;
+
+ if (useAdjustMode_) {
+ szImg = image_.size();
+ switch(adjustMode_)
+ {
+ case MaxFit:
+ szImg.scale(szView, aspectRatioMode_);
+ break;
+ case Fit:
+ if (szImg.width() > szView.width() || szImg.height() > szView.height() ||
+ szImg.width() < image_.width()) {
+ szImg.scale(szView, aspectRatioMode_);
+ }
+ szImg = szImg.boundedTo(image_.size());
+ if (szImg.width() < 1 || szImg.height() < 1) {
+ return;
+ }
+ break;
+ case Origin:
+ break;
+ case Stretch:
+ szImg = szView;
+ break;
+ }
+ }
+
+ imageSize_ = szImg;
+ label_->resize(imageSize_);
+ label_->setPixmap(scaleImage(imageSize_));
+}
+
+void FQTermCanvas::resizeEvent(QResizeEvent * event) {
+ if (useAdjustMode_){
+ autoAdjust();
+ }
+ else adjustSize(size());
+ QScrollArea::resizeEvent(event);
+}
+
+QMenu* FQTermCanvas::menu() {
+ return menu_;
+}
+
+
+QToolBar* FQTermCanvas::ToolBar() {
+ return toolBar_;
+}
+
+void FQTermCanvas::SetAdjustMode(AdjustMode am) {
+ adjustMode_ = am;
+ if (adjustMode_ == Stretch) {
+ aspectRatioMode_ = Qt::IgnoreAspectRatio;
+ }
+ else {
+ aspectRatioMode_ = Qt::KeepAspectRatio;
+ }
+ autoAdjust();
+}
+
+void FQTermCanvas::SetAdjustMode() {
+ SetAdjustMode(AdjustMode((((QAction*)sender())->data()).toInt()));
+}
+
+void FQTermCanvas::openDir() {
+ QString poolPath = config_->getItemValue("preference", "pool");
+ if (poolPath.isEmpty()) {
+ poolPath = getPath(USER_CONFIG) + "pool/";
+ }
+#ifdef WIN32
+ QString path = "file:///" + poolPath;
+#else
+ QString path = "file://" + poolPath;
+#endif
+ QDesktopServices::openUrl(path);
+}
+
+void FQTermCanvas::updateImage(const QString& filename)
+{
+ if (QFileInfo(filename).absoluteFilePath().toLower() == fileName_) {
+ loadImage(fileName_);
+ }
+
+}
+
+
+} // namespace FQTerm
+
+#include "fqterm_canvas.moc"