From bd0f3345a938b35ce6a12f6150373b0955b8dd12 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 10 Jul 2011 15:24:15 -0500 Subject: Add Qt3 development HEAD version --- examples/showimg/README | 14 + examples/showimg/imagefip.cpp | 61 ++++ examples/showimg/imagefip.h | 31 ++ examples/showimg/imagetexteditor.cpp | 141 ++++++++ examples/showimg/imagetexteditor.h | 46 +++ examples/showimg/main.cpp | 56 +++ examples/showimg/showimg.cpp | 672 +++++++++++++++++++++++++++++++++++ examples/showimg/showimg.doc | 29 ++ examples/showimg/showimg.h | 93 +++++ examples/showimg/showimg.pro | 14 + 10 files changed, 1157 insertions(+) create mode 100644 examples/showimg/README create mode 100644 examples/showimg/imagefip.cpp create mode 100644 examples/showimg/imagefip.h create mode 100644 examples/showimg/imagetexteditor.cpp create mode 100644 examples/showimg/imagetexteditor.h create mode 100644 examples/showimg/main.cpp create mode 100644 examples/showimg/showimg.cpp create mode 100644 examples/showimg/showimg.doc create mode 100644 examples/showimg/showimg.h create mode 100644 examples/showimg/showimg.pro (limited to 'examples/showimg') diff --git a/examples/showimg/README b/examples/showimg/README new file mode 100644 index 0000000..a6c9ca9 --- /dev/null +++ b/examples/showimg/README @@ -0,0 +1,14 @@ +This example demonstrates how to read in and display images, and the +conversion facilities available. The CuteWidget can read a file into +a pixmap and resizes the displayed pixmap when the widget is resized. + +Note that the function CuteWidget::paintEvent uses the drawPixmap function +of QPainter to display the pixmap, the bitBlt function can also be used to +display pixmaps. + +If you have installed the Qt imageio extension (see extensions/imageio +in your Qt directory), you can build using that extension. + +Some of the conversion options will have no effect, depending on the +display hardware used. Generally, these are disabled. + diff --git a/examples/showimg/imagefip.cpp b/examples/showimg/imagefip.cpp new file mode 100644 index 0000000..c7f3f2f --- /dev/null +++ b/examples/showimg/imagefip.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "imagefip.h" +#include + +/* XPM */ +static const char *image_xpm[] = { +"17 15 9 1", +" c #7F7F7F", +". c #FFFFFF", +"X c #00B6FF", +"o c #BFBFBF", +"O c #FF6C00", +"+ c #000000", +"@ c #0000FF", +"# c #6CFF00", +"$ c #FFB691", +" ..XX", +" ........o .XXX", +" .OOOOOOOo. XXX+", +" .O@@@@@@+++XXX++", +" .O@@@@@@O.XXX+++", +" .O@@@@@@OXXX+++.", +" .O######XXX++...", +" .O#####XXX++....", +" .O##$#$XX+o+....", +" .O#$$$$$+.o+....", +" .O##$$##O.o+....", +" .OOOOOOOO.o+....", +" ..........o+....", +" ooooooooooo+....", +"+++++++++++++...." +}; + +ImageIconProvider::ImageIconProvider( QWidget *parent, const char *name ) : + QFileIconProvider( parent, name ), + imagepm(image_xpm) +{ + fmts = QImage::inputFormats(); +} + +ImageIconProvider::~ImageIconProvider() +{ +} + +const QPixmap * ImageIconProvider::pixmap( const QFileInfo &fi ) +{ + QString ext = fi.extension().upper(); + if ( fmts.contains(ext) ) { + return &imagepm; + } else { + return QFileIconProvider::pixmap(fi); + } +} diff --git a/examples/showimg/imagefip.h b/examples/showimg/imagefip.h new file mode 100644 index 0000000..d4710da --- /dev/null +++ b/examples/showimg/imagefip.h @@ -0,0 +1,31 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef IMAGEFIP_H +#define IMAGEFIP_H + +#include +#include +#include + +class ImageIconProvider : public QFileIconProvider +{ + Q_OBJECT + QStrList fmts; + QPixmap imagepm; + +public: + ImageIconProvider( QWidget *parent=0, const char *name=0 ); + ~ImageIconProvider(); + + const QPixmap * pixmap( const QFileInfo &fi ); +}; + + +#endif // IMAGEFIP_H diff --git a/examples/showimg/imagetexteditor.cpp b/examples/showimg/imagetexteditor.cpp new file mode 100644 index 0000000..b3f34d9 --- /dev/null +++ b/examples/showimg/imagetexteditor.cpp @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "imagetexteditor.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +ImageTextEditor::ImageTextEditor( QImage& i, QWidget *parent, const char *name, WFlags f ) : + QDialog(parent,name,TRUE,f), + image(i) +{ + QVBoxLayout* vbox = new QVBoxLayout(this,8); + vbox->setAutoAdd(TRUE); + + QGrid* controls = new QGrid(3,QGrid::Horizontal,this); + controls->setSpacing(8); + QLabel* l; + l=new QLabel("Language",controls); l->setAlignment(AlignCenter); + l=new QLabel("Key",controls); l->setAlignment(AlignCenter); + (void)new QLabel("",controls); // dummy + languages = new QComboBox(controls); + keys = new QComboBox(controls); + QPushButton* remove = new QPushButton("Remove",controls); + + newlang = new QLineEdit(controls); + newkey = new QLineEdit(controls); + QPushButton* add = new QPushButton("Add",controls); + + text = new QMultiLineEdit(this); + + QHBox* hbox = new QHBox(this); + QPushButton* cancel = new QPushButton("Cancel",hbox); + QPushButton* ok = new QPushButton("OK",hbox); + + connect(add,SIGNAL(clicked()), + this,SLOT(addText())); + + connect(remove,SIGNAL(clicked()), + this,SLOT(removeText())); + + connect(ok,SIGNAL(clicked()), + this,SLOT(accept())); + + connect(cancel,SIGNAL(clicked()), + this,SLOT(reject())); + + connect(languages,SIGNAL(activated(int)), + this,SLOT(updateText())); + + connect(keys,SIGNAL(activated(int)), + this,SLOT(updateText())); + + imageChanged(); +} + +ImageTextEditor::~ImageTextEditor() +{ +} + +void ImageTextEditor::imageChanged() +{ + languages->clear(); + keys->clear(); + text->clear(); + languages->insertItem(""); + + languages->insertStringList(image.textLanguages()); + keys->insertStringList(image.textKeys()); + + updateText(); +} + +void ImageTextEditor::accept() +{ + storeText(); + QDialog::accept(); +} + +void ImageTextEditor::updateText() +{ + storeText(); + newlang->setText(languages->currentText()); + newkey->setText(keys->currentText()); + QString t = image.text(currKey(),currLang()); + + text->setText(t); +} + +QString ImageTextEditor::currKey() +{ + return newkey->text(); +} + +QString ImageTextEditor::currLang() +{ + QString l = newlang->text(); + if ( l=="" ) + l = QString::null; + return l; +} + +QString ImageTextEditor::currText() +{ + QString t = text->text(); + if ( t.isNull() ) t = ""; + return t; +} + + +void ImageTextEditor::removeText() +{ + image.setText(currKey(),currLang(),QString::null); +} + +void ImageTextEditor::addText() +{ + storeText(); +} + +void ImageTextEditor::storeText() +{ + if ( currKey().length() > 0 ) { + image.setText(currKey(),currLang(),currText()); + } +} diff --git a/examples/showimg/imagetexteditor.h b/examples/showimg/imagetexteditor.h new file mode 100644 index 0000000..0153771 --- /dev/null +++ b/examples/showimg/imagetexteditor.h @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef IMAGETEXTEDITOR_H +#define IMAGETEXTEDITOR_H + +#include + +class QImage; +class QComboBox; +class QListBox; +class QLineEdit; +class QMultiLineEdit; + +class ImageTextEditor : public QDialog +{ + Q_OBJECT +public: + ImageTextEditor( QImage& i, QWidget *parent=0, const char *name=0, WFlags f=0 ); + ~ImageTextEditor(); + void accept(); +public slots: + void imageChanged(); + void updateText(); + void addText(); + void removeText(); +private: + void storeText(); + QImage& image; + QComboBox* languages; + QComboBox* keys; + QMultiLineEdit* text; + QLineEdit* newlang; + QLineEdit* newkey; + QString currKey(); + QString currLang(); + QString currText(); +}; + +#endif // IMAGETEXTEDITOR_H diff --git a/examples/showimg/main.cpp b/examples/showimg/main.cpp new file mode 100644 index 0000000..5ee9503 --- /dev/null +++ b/examples/showimg/main.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "showimg.h" +#include "imagefip.h" +#include +#include + +int main( int argc, char **argv ) +{ + if ( argc > 1 && QString(argv[1]) == "-m" ) { + QApplication::setColorSpec( QApplication::ManyColor ); + argc--; + argv++; + } + else if ( argc > 1 && QString(argv[1]) == "-n" ) { + QApplication::setColorSpec( QApplication::NormalColor ); + argc--; + argv++; + } + else { + QApplication::setColorSpec( QApplication::CustomColor ); + } + + QApplication a( argc, argv ); + + ImageIconProvider iip; + QFileDialog::setIconProvider( &iip ); + + if ( argc <= 1 ) { + // Create a window which looks after its own existence. + ImageViewer *w = + new ImageViewer(0, "new window", Qt::WDestructiveClose | Qt::WResizeNoErase ); + w->setCaption("Qt Example - Image Viewer"); + w->show(); + } else { + for ( int i=1; isetCaption("Qt Example - Image Viewer"); + w->loadImage( argv[i] ); + w->show(); + } + } + + QObject::connect(qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit())); + + return a.exec(); +} diff --git a/examples/showimg/showimg.cpp b/examples/showimg/showimg.cpp new file mode 100644 index 0000000..1ee9847 --- /dev/null +++ b/examples/showimg/showimg.cpp @@ -0,0 +1,672 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "showimg.h" +#include "imagetexteditor.h" +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + In the constructor, we just pass the standard parameters on to + QWidget. + + The menu uses a single slot to simplify the process of adding + more items to the options menu. +*/ +ImageViewer::ImageViewer( QWidget *parent, const char *name, int wFlags ) + : QWidget( parent, name, wFlags ), + conversion_flags( PreferDither ), + helpmsg( 0 ) +{ + pickx = -1; + picky = -1; + clickx = -1; + clicky = -1; + alloc_context = 0; + + menubar = new QMenuBar(this); + menubar->setSeparator( QMenuBar::InWindowsStyle ); + + QStrList fmt = QImage::outputFormats(); + saveimage = new QPopupMenu( menubar ); + savepixmap = new QPopupMenu( menubar ); + for (const char* f = fmt.first(); f; f = fmt.next()) { + saveimage->insertItem( f ); + savepixmap->insertItem( f ); + } + connect( saveimage, SIGNAL(activated(int)), this, SLOT(saveImage(int)) ); + connect( savepixmap, SIGNAL(activated(int)), this, SLOT(savePixmap(int)) ); + + file = new QPopupMenu( menubar ); + menubar->insertItem( "&File", file ); + file->insertItem( "&New window", this, SLOT(newWindow()), CTRL+Key_N ); + file->insertItem( "&Open...", this, SLOT(openFile()), CTRL+Key_O ); + si = file->insertItem( "Save image", saveimage ); + sp = file->insertItem( "Save pixmap", savepixmap ); + file->insertSeparator(); + file->insertItem( "E&xit", qApp, SLOT(quit()), CTRL+Key_Q ); + + edit = new QPopupMenu( menubar ); + menubar->insertItem( "&Edit", edit ); + edit->insertItem("&Copy", this, SLOT(copy()), CTRL+Key_C); + edit->insertItem("&Paste", this, SLOT(paste()), CTRL+Key_V); + edit->insertSeparator(); + edit->insertItem("&Horizontal flip", this, SLOT(hFlip()), ALT+Key_H); + edit->insertItem("&Vertical flip", this, SLOT(vFlip()), ALT+Key_V); + edit->insertItem("&Rotate 180", this, SLOT(rot180()), ALT+Key_R); + edit->insertSeparator(); + edit->insertItem("&Text...", this, SLOT(editText())); + edit->insertSeparator(); + t1 = edit->insertItem( "Convert to &1 bit", this, SLOT(to1Bit()) ); + t8 = edit->insertItem( "Convert to &8 bit", this, SLOT(to8Bit()) ); + t32 = edit->insertItem( "Convert to &32 bit", this, SLOT(to32Bit()) ); + + options = new QPopupMenu( menubar ); + menubar->insertItem( "&Options", options ); + ac = options->insertItem( "AutoColor" ); + co = options->insertItem( "ColorOnly" ); + mo = options->insertItem( "MonoOnly" ); + options->insertSeparator(); + fd = options->insertItem( "DiffuseDither" ); + bd = options->insertItem( "OrderedDither" ); + td = options->insertItem( "ThresholdDither" ); + options->insertSeparator(); + ta = options->insertItem( "ThresholdAlphaDither" ); + ba = options->insertItem( "OrderedAlphaDither" ); + fa = options->insertItem( "DiffuseAlphaDither" ); + options->insertSeparator(); + ad = options->insertItem( "PreferDither" ); + dd = options->insertItem( "AvoidDither" ); + options->insertSeparator(); + ss = options->insertItem( "Smooth scaling" ); + cc = options->insertItem( "Use color context" ); + if ( QApplication::colorSpec() == QApplication::ManyColor ) + options->setItemEnabled( cc, FALSE ); + options->setCheckable( TRUE ); + setMenuItemFlags(); + + menubar->insertSeparator(); + + QPopupMenu* help = new QPopupMenu( menubar ); + menubar->insertItem( "&Help", help ); + help->insertItem( "Help!", this, SLOT(giveHelp()), CTRL+Key_H ); + + connect( options, SIGNAL(activated(int)), this, SLOT(doOption(int)) ); + + status = new QLabel(this); + status->setFrameStyle( QFrame::WinPanel | QFrame::Sunken ); + status->setFixedHeight( fontMetrics().height() + 4 ); + + setMouseTracking( TRUE ); +} + +ImageViewer::~ImageViewer() +{ + if ( alloc_context ) + QColor::destroyAllocContext( alloc_context ); + if ( other == this ) + other = 0; +} + +/* + This function modifies the conversion_flags when an options menu item + is selected, then ensures all menu items are up to date, and reconverts + the image if possibly necessary. +*/ +void ImageViewer::doOption(int item) +{ + if ( item == ss || item == cc ) { + // Toggle + bool newbool = !options->isItemChecked(item); + options->setItemChecked(item, newbool); + // And reconvert... + reconvertImage(); + repaint(image.hasAlphaBuffer()); // show image in widget + return; + } + + if ( options->isItemChecked( item ) ) return; // They are all radio buttons + + int ocf = conversion_flags; + + if ( item == ac ) { + conversion_flags = ( conversion_flags & ~ColorMode_Mask ) | AutoColor; + } else if ( item == co ) { + conversion_flags = ( conversion_flags & ~ColorMode_Mask ) | ColorOnly; + } else if ( item == mo ) { + conversion_flags = ( conversion_flags & ~ColorMode_Mask ) | MonoOnly; + } else if ( item == fd ) { + conversion_flags = ( conversion_flags & ~Dither_Mask ) | DiffuseDither; + } else if ( item == bd ) { + conversion_flags = ( conversion_flags & ~Dither_Mask ) | OrderedDither; + } else if ( item == td ) { + conversion_flags = ( conversion_flags & ~Dither_Mask ) | ThresholdDither; + } else if ( item == ta ) { + conversion_flags = ( conversion_flags & ~AlphaDither_Mask ) | ThresholdAlphaDither; + } else if ( item == fa ) { + conversion_flags = ( conversion_flags & ~AlphaDither_Mask ) | DiffuseAlphaDither; + } else if ( item == ba ) { + conversion_flags = ( conversion_flags & ~AlphaDither_Mask ) | OrderedAlphaDither; + } else if ( item == ad ) { + conversion_flags = ( conversion_flags & ~DitherMode_Mask ) | PreferDither; + } else if ( item == dd ) { + conversion_flags = ( conversion_flags & ~DitherMode_Mask ) | AvoidDither; + } + + if ( ocf != conversion_flags ) { + setMenuItemFlags(); + // And reconvert... + reconvertImage(); + repaint(image.hasAlphaBuffer()); // show image in widget + } +} + +/* + Set the options menu to reflect the conversion_flags value. +*/ +void ImageViewer::setMenuItemFlags() +{ + // File + bool valid_image = pm.size() != QSize( 0, 0 ); + file->setItemEnabled( si, valid_image ); + file->setItemEnabled( sp, valid_image ); + + // Edit + edit->setItemEnabled( t1, image.depth() != 1 ); + edit->setItemEnabled( t8, image.depth() != 8 ); + edit->setItemEnabled( t32, image.depth() != 32 ); + + // Options + bool may_need_color_dithering = + !valid_image + || image.depth() == 32 && QPixmap::defaultDepth() < 24; + bool may_need_dithering = may_need_color_dithering + || image.depth() > 1 && options->isItemChecked(mo) + || image.depth() > 1 && QPixmap::defaultDepth() == 1; + bool has_alpha_mask = !valid_image || image.hasAlphaBuffer(); + + options->setItemEnabled( fd, may_need_dithering ); + options->setItemEnabled( bd, may_need_dithering ); + options->setItemEnabled( td, may_need_dithering ); + + options->setItemEnabled( ta, has_alpha_mask ); + options->setItemEnabled( fa, has_alpha_mask ); + options->setItemEnabled( ba, has_alpha_mask ); + + options->setItemEnabled( ad, may_need_color_dithering ); + options->setItemEnabled( dd, may_need_color_dithering ); + + options->setItemChecked( ac, (conversion_flags & ColorMode_Mask) == AutoColor ); + options->setItemChecked( co, (conversion_flags & ColorMode_Mask) == ColorOnly ); + options->setItemChecked( mo, (conversion_flags & ColorMode_Mask) == MonoOnly ); + options->setItemChecked( fd, (conversion_flags & Dither_Mask) == DiffuseDither ); + options->setItemChecked( bd, (conversion_flags & Dither_Mask) == OrderedDither ); + options->setItemChecked( td, (conversion_flags & Dither_Mask) == ThresholdDither ); + options->setItemChecked( ta, (conversion_flags & AlphaDither_Mask) == ThresholdAlphaDither ); + options->setItemChecked( fa, (conversion_flags & AlphaDither_Mask) == DiffuseAlphaDither ); + options->setItemChecked( ba, (conversion_flags & AlphaDither_Mask) == OrderedAlphaDither ); + options->setItemChecked( ad, (conversion_flags & DitherMode_Mask) == PreferDither ); + options->setItemChecked( dd, (conversion_flags & DitherMode_Mask) == AvoidDither ); +} + +void ImageViewer::updateStatus() +{ + if ( pm.size() == QSize( 0, 0 ) ) { + if ( !filename.isEmpty() ) + status->setText("Could not load image"); + else + status->setText("No image - select Open from File menu."); + } else { + QString message, moremsg; + message.sprintf("%dx%d", image.width(), image.height()); + if ( pm.size() != pmScaled.size() ) { + moremsg.sprintf(" [%dx%d]", pmScaled.width(), + pmScaled.height()); + message += moremsg; + } + moremsg.sprintf(", %d bits ", image.depth()); + message += moremsg; + if (image.valid(pickx,picky)) { + moremsg.sprintf("(%d,%d)=#%0*x ", + pickx, picky, + image.hasAlphaBuffer() ? 8 : 6, + image.pixel(pickx,picky)); + message += moremsg; + } + if ( image.numColors() > 0 ) { + if (image.valid(pickx,picky)) { + moremsg.sprintf(", %d/%d colors", image.pixelIndex(pickx,picky), + image.numColors()); + } else { + moremsg.sprintf(", %d colors", image.numColors()); + } + message += moremsg; + } + if ( image.hasAlphaBuffer() ) { + if ( image.depth() == 8 ) { + int i; + bool alpha[256]; + int nalpha=0; + + for (i=0; i<256; i++) + alpha[i] = FALSE; + + for (i=0; i> 24; + if (!alpha[alevel]) { + alpha[alevel] = TRUE; + nalpha++; + } + } + moremsg.sprintf(", %d alpha levels", nalpha); + } else { + // Too many pixels to bother counting. + moremsg = ", 8-bit alpha channel"; + } + message += moremsg; + } + status->setText(message); + } +} + +/* + This function saves the image. +*/ +void ImageViewer::saveImage( int item ) +{ + const char* fmt = saveimage->text(item); + QString savefilename = QFileDialog::getSaveFileName(QString::null, QString::null, + this, filename); + if ( !savefilename.isEmpty() ) + if ( !image.save( savefilename, fmt ) ) + QMessageBox::warning( this, "Save failed", "Error saving file" ); +} + +/* + This function saves the converted image. +*/ +void ImageViewer::savePixmap( int item ) +{ + const char* fmt = savepixmap->text(item); + QString savefilename = QFileDialog::getSaveFileName(QString::null, + QString::null, this, filename); + if ( !savefilename.isEmpty() ) + if ( !pmScaled.save( savefilename, fmt ) ) + QMessageBox::warning( this, "Save failed", "Error saving file" ); +} + + +void ImageViewer::newWindow() +{ + ImageViewer* that = new ImageViewer(0, "new window", WDestructiveClose); + that->options->setItemChecked( that->cc, useColorContext() ); + that->show(); +} + +/* + This function is the slot for processing the Open menu item. +*/ +void ImageViewer::openFile() +{ + QString newfilename = QFileDialog::getOpenFileName( QString::null, + QString::null, + this ); + if ( !newfilename.isEmpty() ) { + loadImage( newfilename ) ; + repaint(); // show image in widget + } +} + +/* + This function loads an image from a file and resizes the widget to + exactly fit the image size. If the file was not found or the image + format was unknown it will resize the widget to fit the errorText + message (see above) displayed in the current font. + + Returns TRUE if the image was successfully loaded. +*/ + +bool ImageViewer::loadImage( const QString& fileName ) +{ + filename = fileName; + bool ok = FALSE; + if ( !filename.isEmpty() ) { + QApplication::setOverrideCursor( waitCursor ); // this might take time + ok = image.load(filename, 0); + pickx = -1; + clickx = -1; + if ( ok ) + ok = reconvertImage(); + if ( ok ) { + setCaption( filename ); // set window caption + int w = pm.width(); + int h = pm.height(); + + const int reasonable_width = 128; + if ( w < reasonable_width ) { + // Integer scale up to something reasonable + int multiply = ( reasonable_width + w - 1 ) / w; + w *= multiply; + h *= multiply; + } + + h += menubar->heightForWidth(w) + status->height(); + resize( w, h ); // we resize to fit image + } else { + pm.resize(0,0); // couldn't load image + update(); + } + QApplication::restoreOverrideCursor(); // restore original cursor + } + updateStatus(); + setMenuItemFlags(); + return ok; +} + +bool ImageViewer::reconvertImage() +{ + bool success = FALSE; + + if ( image.isNull() ) return FALSE; + + if ( alloc_context ) { + QColor::destroyAllocContext( alloc_context ); + alloc_context = 0; + } + if ( useColorContext() ) { + alloc_context = QColor::enterAllocContext(); + // Clear the image to hide flickering palette + QPainter painter(this); + painter.eraseRect(0, menubar->heightForWidth( width() ), width(), height()); + } + + QApplication::setOverrideCursor( waitCursor ); // this might take time + if ( pm.convertFromImage(image, conversion_flags) ) + { + pmScaled = QPixmap(); + scale(); + resize( width(), height() ); + success = TRUE; // load successful + } else { + pm.resize(0,0); // couldn't load image + } + updateStatus(); + setMenuItemFlags(); + QApplication::restoreOverrideCursor(); // restore original cursor + + if ( useColorContext() ) + QColor::leaveAllocContext(); + + return success; // TRUE if loaded OK +} + +bool ImageViewer::smooth() const +{ + return options->isItemChecked(ss); +} + +bool ImageViewer::useColorContext() const +{ + return options->isItemChecked(cc); +} + +/* + This functions scales the pixmap in the member variable "pm" to fit the + widget size and puts the resulting pixmap in the member variable "pmScaled". +*/ + +void ImageViewer::scale() +{ + int h = height() - menubar->heightForWidth( width() ) - status->height(); + + if ( image.isNull() ) return; + + QApplication::setOverrideCursor( waitCursor ); // this might take time + if ( width() == pm.width() && h == pm.height() ) + { // no need to scale if widget + pmScaled = pm; // size equals pixmap size + } else { + if (smooth()) { + pmScaled.convertFromImage(image.smoothScale(width(), h), + conversion_flags); + } else { + QWMatrix m; // transformation matrix + m.scale(((double)width())/pm.width(),// define scale factors + ((double)h)/pm.height()); + pmScaled = pm.xForm( m ); // create scaled pixmap + } + } + QApplication::restoreOverrideCursor(); // restore original cursor +} + +/* + The resize event handler, if a valid pixmap was loaded it will call + scale() to fit the pixmap to the new widget size. +*/ + +void ImageViewer::resizeEvent( QResizeEvent * ) +{ + status->setGeometry(0, height() - status->height(), + width(), status->height()); + + if ( pm.size() == QSize( 0, 0 ) ) // we couldn't load the image + return; + + int h = height() - menubar->heightForWidth( width() ) - status->height(); + if ( width() != pmScaled.width() || h != pmScaled.height()) + { // if new size, + scale(); // scale pmScaled to window + updateStatus(); + } + if ( image.hasAlphaBuffer() ) + erase(); +} + +bool ImageViewer::convertEvent( QMouseEvent* e, int& x, int& y) +{ + if ( pm.size() != QSize( 0, 0 ) ) { + int h = height() - menubar->heightForWidth( width() ) - status->height(); + int nx = e->x() * image.width() / width(); + int ny = (e->y()-menubar->heightForWidth( width() )) * image.height() / h; + if (nx != x || ny != y ) { + x = nx; + y = ny; + updateStatus(); + return TRUE; + } + } + return FALSE; +} + +void ImageViewer::mousePressEvent( QMouseEvent *e ) +{ + may_be_other = convertEvent(e, clickx, clicky); +} + +void ImageViewer::mouseReleaseEvent( QMouseEvent * ) +{ + if ( may_be_other ) + other = this; +} + +/* + Record the pixel position of interest. +*/ +void ImageViewer::mouseMoveEvent( QMouseEvent *e ) +{ + if (convertEvent(e,pickx,picky)) { + updateStatus(); + if ((e->state()&LeftButton)) { + may_be_other = FALSE; + if ( clickx >= 0 && other) { + copyFrom(other); + } + } + } +} + +/* + Draws the portion of the scaled pixmap that needs to be updated or prints + an error message if no legal pixmap has been loaded. +*/ + +void ImageViewer::paintEvent( QPaintEvent *e ) +{ + if ( pm.size() != QSize( 0, 0 ) ) { // is an image loaded? + QPainter painter(this); + painter.setClipRect(e->rect()); + painter.drawPixmap(0, menubar->heightForWidth( width() ), pmScaled); + } +} + + +/* + Explain anything that might be confusing. +*/ +void ImageViewer::giveHelp() +{ + if (!helpmsg) { + QString helptext = + "Usage: showimg [-m] filename ..." + "
" + "-m - use ManyColor color spec" + "
" + "

Supported input formats:" + "

"; + helptext += QImage::inputFormatList().join(", "); + helptext += "
"; + + helpmsg = new QMessageBox( "Help", helptext, + QMessageBox::Information, QMessageBox::Ok, 0, 0, 0, 0, FALSE ); + } + helpmsg->show(); + helpmsg->raise(); +} + +void ImageViewer::copyFrom(ImageViewer* s) +{ + if ( clickx >= 0 ) { + int dx = clickx; + int dy = clicky; + int sx = s->clickx; + int sy = s->clicky; + int sw = QABS(clickx - pickx)+1; + int sh = QABS(clicky - picky)+1; + if ( clickx > pickx ) { + dx = pickx; + sx -= sw-1; + } + if ( clicky > picky ) { + dy = picky; + sy -= sh-1; + } + bitBlt( &image, dx, dy, &s->image, sx, sy, sw, sh ); + reconvertImage(); + repaint( image.hasAlphaBuffer() ); + } +} +ImageViewer* ImageViewer::other = 0; + +void ImageViewer::hFlip() +{ + setImage(image.mirror(TRUE,FALSE)); +} + +void ImageViewer::vFlip() +{ + setImage(image.mirror(FALSE,TRUE)); +} + +void ImageViewer::rot180() +{ + setImage(image.mirror(TRUE,TRUE)); +} + +void ImageViewer::copy() +{ +#ifndef QT_NO_MIMECLIPBOARD + QApplication::clipboard()->setImage(image); // Less information loss +#endif +} + +void ImageViewer::paste() +{ +#ifndef QT_NO_MIMECLIPBOARD + QImage p = QApplication::clipboard()->image(); + if ( !p.isNull() ) { + filename = "pasted"; + setImage(p); + } +#endif +} + +void ImageViewer::setImage(const QImage& newimage) +{ + image = newimage; + + pickx = -1; + clickx = -1; + setCaption( filename ); // set window caption + int w = image.width(); + int h = image.height(); + if ( !w ) + return; + + const int reasonable_width = 128; + if ( w < reasonable_width ) { + // Integer scale up to something reasonable + int multiply = ( reasonable_width + w - 1 ) / w; + w *= multiply; + h *= multiply; + } + + h += menubar->heightForWidth(w) + status->height(); + resize( w, h ); // we resize to fit image + + reconvertImage(); + repaint( image.hasAlphaBuffer() ); + + updateStatus(); + setMenuItemFlags(); +} + +void ImageViewer::editText() +{ + ImageTextEditor editor(image,this); + editor.exec(); +} + +void ImageViewer::to1Bit() +{ + toBitDepth(1); +} + +void ImageViewer::to8Bit() +{ + toBitDepth(8); +} + +void ImageViewer::to32Bit() +{ + toBitDepth(32); +} + +void ImageViewer::toBitDepth(int d) +{ + image = image.convertDepth(d); + reconvertImage(); + repaint( image.hasAlphaBuffer() ); +} diff --git a/examples/showimg/showimg.doc b/examples/showimg/showimg.doc new file mode 100644 index 0000000..d501bb8 --- /dev/null +++ b/examples/showimg/showimg.doc @@ -0,0 +1,29 @@ +/* +*/ +/*! \page showimg-example.html + + \ingroup examples + \title Show Image + + This example reads and displays an image in any supported image + format (GIF, BMP, PPM, XMP, etc.). + +
+ + Header file: + + \include showimg/showimg.h + +
+ + Implementation: + + \include showimg/showimg.cpp + +
+ + Main: + + \include showimg/main.cpp +*/ + diff --git a/examples/showimg/showimg.h b/examples/showimg/showimg.h new file mode 100644 index 0000000..a9c63e0 --- /dev/null +++ b/examples/showimg/showimg.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef SHOWIMG_H +#define SHOWIMG_H + +#include +#include + + +class QLabel; +class QMenuBar; +class QPopupMenu; + +class ImageViewer : public QWidget +{ + Q_OBJECT +public: + ImageViewer( QWidget *parent=0, const char *name=0, int wFlags=0 ); + ~ImageViewer(); + bool loadImage( const QString& ); +protected: + void paintEvent( QPaintEvent * ); + void resizeEvent( QResizeEvent * ); + void mousePressEvent( QMouseEvent * ); + void mouseReleaseEvent( QMouseEvent * ); + void mouseMoveEvent( QMouseEvent * ); + +private: + void scale(); + int conversion_flags; + bool smooth() const; + bool useColorContext() const; + int alloc_context; + bool convertEvent( QMouseEvent* e, int& x, int& y ); + QString filename; + QImage image; // the loaded image + QPixmap pm; // the converted pixmap + QPixmap pmScaled; // the scaled pixmap + + QMenuBar *menubar; + QPopupMenu *file; + QPopupMenu *saveimage; + QPopupMenu *savepixmap; + QPopupMenu *edit; + QPopupMenu *options; + + QWidget *helpmsg; + QLabel *status; + int si, sp, ac, co, mo, fd, bd, // Menu item ids + td, ta, ba, fa, au, ad, dd, + ss, cc, t1, t8, t32; + void updateStatus(); + void setMenuItemFlags(); + bool reconvertImage(); + int pickx, picky; + int clickx, clicky; + bool may_be_other; + static ImageViewer* other; + void setImage(const QImage& newimage); + +private slots: + void to1Bit(); + void to8Bit(); + void to32Bit(); + void toBitDepth(int); + + void copy(); + void paste(); + + void hFlip(); + void vFlip(); + void rot180(); + + void editText(); + + void newWindow(); + void openFile(); + void saveImage(int); + void savePixmap(int); + void giveHelp(); + void doOption(int); + void copyFrom(ImageViewer*); +}; + + +#endif // SHOWIMG_H diff --git a/examples/showimg/showimg.pro b/examples/showimg/showimg.pro new file mode 100644 index 0000000..b2df094 --- /dev/null +++ b/examples/showimg/showimg.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +TARGET = showimg + +CONFIG += qt warn_on release +DEPENDPATH = ../../include + +REQUIRES = full-config + +HEADERS = showimg.h imagetexteditor.h \ + imagefip.h +SOURCES = main.cpp \ + imagetexteditor.cpp \ + showimg.cpp \ + imagefip.cpp -- cgit v1.2.3