author | alwin <alwin> | 2005-03-23 19:28:15 (UTC) |
---|---|---|
committer | alwin <alwin> | 2005-03-23 19:28:15 (UTC) |
commit | 7f2338c33a3dd22d7f851909fb023a9364fdafd0 (patch) (side-by-side diff) | |
tree | d39ed1ff22f535c43b6c43f097c3b9eb02ad3b37 /noncore/unsupported | |
parent | 76ea5ee6e306a4ee9fe6831dbe4c13ee53f6cdf5 (diff) | |
download | opie-7f2338c33a3dd22d7f851909fb023a9364fdafd0.zip opie-7f2338c33a3dd22d7f851909fb023a9364fdafd0.tar.gz opie-7f2338c33a3dd22d7f851909fb023a9364fdafd0.tar.bz2 |
showimg -> unsupported
-rw-r--r-- | noncore/unsupported/config.in | 2 | ||||
-rw-r--r-- | noncore/unsupported/showimg/.cvsignore | 4 | ||||
-rw-r--r-- | noncore/unsupported/showimg/ImageFileSelector.cpp | 262 | ||||
-rw-r--r-- | noncore/unsupported/showimg/ImageFileSelector.h | 134 | ||||
-rw-r--r-- | noncore/unsupported/showimg/README | 14 | ||||
-rw-r--r-- | noncore/unsupported/showimg/config.in | 4 | ||||
-rw-r--r-- | noncore/unsupported/showimg/main.cpp | 28 | ||||
-rw-r--r-- | noncore/unsupported/showimg/opie-showimg.control | 11 | ||||
-rw-r--r-- | noncore/unsupported/showimg/settingsdialog.cpp | 86 | ||||
-rw-r--r-- | noncore/unsupported/showimg/settingsdialog.h | 49 | ||||
-rw-r--r-- | noncore/unsupported/showimg/settingsdialogbase.cpp | 102 | ||||
-rw-r--r-- | noncore/unsupported/showimg/settingsdialogbase.h | 45 | ||||
-rw-r--r-- | noncore/unsupported/showimg/showimg.cpp | 1242 | ||||
-rw-r--r-- | noncore/unsupported/showimg/showimg.h | 289 | ||||
-rw-r--r-- | noncore/unsupported/showimg/showimg.pro | 9 |
15 files changed, 2281 insertions, 0 deletions
diff --git a/noncore/unsupported/config.in b/noncore/unsupported/config.in index 676e953..dfd46de 100644 --- a/noncore/unsupported/config.in +++ b/noncore/unsupported/config.in @@ -4,3 +4,5 @@ source noncore/unsupported/mail2/config.in source noncore/unsupported/mailit/config.in source noncore/unsupported/oipkg/config.in source noncore/unsupported/qpdf/config.in +source noncore/unsupported/showimg/config.in +source noncore/unsupported/ubrowser/config.in diff --git a/noncore/unsupported/showimg/.cvsignore b/noncore/unsupported/showimg/.cvsignore new file mode 100644 index 0000000..93b952d --- a/dev/null +++ b/noncore/unsupported/showimg/.cvsignore @@ -0,0 +1,4 @@ +Makefile* +moc_* +.moc +.obj diff --git a/noncore/unsupported/showimg/ImageFileSelector.cpp b/noncore/unsupported/showimg/ImageFileSelector.cpp new file mode 100644 index 0000000..53cc883 --- a/dev/null +++ b/noncore/unsupported/showimg/ImageFileSelector.cpp @@ -0,0 +1,262 @@ +#include "ImageFileSelector.h" + +/* OPIE */ +#include <opie2/odebug.h> +#include <qpe/qpeapplication.h> +using namespace Opie::Core; + +/* QT */ +#include <qlabel.h> +#include <qfileinfo.h> + +/* STD */ +#include <stdlib.h> + +ThumbWidget::ThumbWidget(QPixmap p,QString text,const DocLnk& f,QWidget *parent,int w) + : QWidget( parent ),fl(f) +{ + setBackgroundMode(NoBackground); + if ( w!=-1 ) + setMinimumSize(w,p.height()+24); + else + setMinimumSize(p.width(),p.height()+24); + description=new QLabel(text,this); + description->setBackgroundColor(colorGroup().base()); + description->setAlignment(AlignCenter); + description->setGeometry(0,height()-24,width(),24); + pixmap=p; +} + +void ThumbWidget::resizeEvent(QResizeEvent *) +{ + description->setGeometry(0,height()-24,width(),24); +} + +void ThumbWidget::paintEvent( QPaintEvent *e ) +{ + QPainter painter(this); + + painter.setClipRect(e->rect()); + painter.fillRect(0,0,width(),height(),QColor(255,255,255)); + painter.drawPixmap((width() - pixmap.width()) / 2,0, pixmap); + +} + +void ThumbWidget::mouseReleaseEvent(QMouseEvent* ) +{ + emit clicked(fl); +} + + + +ImageFileSelectorItem::ImageFileSelectorItem( QListView *parent, const DocLnk &f) + : QListViewItem( parent ), fl( f ) +{ + setText( 0, f.name() ); + QFileInfo fi(f.file()); + setText( 1, (fi.extension()).upper() ); + setPixmap( 0, f.pixmap() ); + + +} + + +ImageFileSelectorItem::~ImageFileSelectorItem() +{ + +} + + +ImageFileSelector::ImageFileSelector( CURRENT_VIEW scv,QWidget *parent,const char * ) + : QWidgetStack(parent) +{ + + detailed=new QListView(this); + + detailed->addColumn (tr("Title")); + detailed->addColumn (tr("Type")); + detailed->setAllColumnsShowFocus( true ); + + tList.setAutoDelete(true); + + thumb =new QScrollView(this); + thumb->setVScrollBarMode (QScrollView::Auto ); + thumb->viewport()->setBackgroundColor(colorGroup().base()); + + background=new QWidget(0); + background->setBackgroundColor(colorGroup().base()); + thumb->addChild(background); + gl = new QGridLayout(background,1,2,4,4); + + + + connect( detailed, SIGNAL( mouseButtonClicked(int,QListViewItem*,const QPoint&,int) ), + this, SLOT( fileClicked(int,QListViewItem*,const QPoint&,int) ) ); + connect( detailed, SIGNAL( mouseButtonPressed(int,QListViewItem*,const QPoint&,int) ), + this, SLOT( filePressed(int,QListViewItem*,const QPoint&,int) ) ); + connect( detailed, SIGNAL( returnPressed(QListViewItem*) ), + this, SLOT( fileClicked(QListViewItem*) ) ); + + cView=UNKNOWN; + setView(scv); + reread(); + +} +ImageFileSelector::~ImageFileSelector() +{ + +} + + +void ImageFileSelector::switchView() +{ + CURRENT_VIEW v=cView; + + if ( v==DETAILED ) + v=THUMBNAIL; + else + v=DETAILED; + setView(v); +} + +void ImageFileSelector::setView(CURRENT_VIEW v) +{ + + if ( v==cView ) + return; + cView=v; + + if ( cView!=DETAILED ) + { + raiseWidget(thumb); + updateSizes(); + } + else + { + raiseWidget(detailed); + updateSizes(); + } + + +} + +void ImageFileSelector::resizeEvent(QResizeEvent *) +{ + updateSizes(); +} + +void ImageFileSelector::updateSizes() +{ + int ww=(detailed->width()-detailed->frameWidth()*2); + double w=(double)ww*0.70; + detailed->setColumnWidth(0,(int)w); + detailed->setColumnWidth(1,ww-(int)w); + background->setMinimumWidth(thumb->visibleWidth()); + thumb->updateScrollBars(); +} + +void ImageFileSelector::reread(bool) +{ +// odebug << "reread" << oendl; + ImageFileSelectorItem *item = (ImageFileSelectorItem *)detailed->selectedItem(); + QString oldFile; + if ( item ) + oldFile = item->file().file(); + detailed->clear(); + tList.clear(); + DocLnkSet files; + Global::findDocuments(&files, "image/*"); + count = files.children().count(); + QListIterator<DocLnk> dit( files.children() ); +// int y=0; +// int x=4; +// int totalHeight=4; + ThumbWidget *l=0; + int width=80; + gl->expand(dit.count()/2,2); + int i,j; + i=j=0; + detailed->setUpdatesEnabled(false); + thumb->setUpdatesEnabled(false); + + for ( ; dit.current(); ++dit ) { + item = new ImageFileSelectorItem( detailed, **dit ); + if ( item->file().file() == oldFile ) + detailed->setCurrentItem( item ); + } + + QListViewItemIterator it( detailed ); + ImageFileSelectorItem *ii; + // iterate through all items of the listview + for ( ; it.current(); ++it ) { + ii=(ImageFileSelectorItem *)it.current(); + QImage img( ii->file().file() ); + if( !img.isNull()) { + img=img.smoothScale(64,64); + QPixmap pix; + pix.convertFromImage(img); + l=new ThumbWidget(pix,ii->file().name(),ii->file(),background,width); + l->setBackgroundColor(colorGroup().base()); + gl->addWidget(l,j,i); + i++; + if ( i==2 ) { + i=0; + j++; + } + tList.append(l); + connect(l,SIGNAL(clicked(const DocLnk&)),this,SLOT(thumbClicked(const DocLnk&))); + } + } + + if ( !detailed->selectedItem() ) + detailed->setCurrentItem( detailed->firstChild() ); + + detailed->setUpdatesEnabled(true); + thumb->setUpdatesEnabled(true); + detailed->update(); + thumb->update(); +} + +int ImageFileSelector::fileCount() +{ + return count; +} +const DocLnk * ImageFileSelector::selected() +{ + odebug << "image selected" << oendl; + ImageFileSelectorItem *item = (ImageFileSelectorItem *) detailed->selectedItem(); + if ( item ) + return new DocLnk( item->file() ); + return 0; +} + + + +void ImageFileSelector::fileClicked( int button, QListViewItem *i, const QPoint &, int ) +{ + if ( !i ) + return; + if ( button == Qt::LeftButton ) + { + fileClicked( i ); + } +} + // pressed to get 'right down' +void ImageFileSelector::filePressed( int, QListViewItem *, const QPoint &, int ) +{ + +} +void ImageFileSelector::fileClicked( QListViewItem *i) +{ + if ( !i ) + return; + emit fileSelected( ( (ImageFileSelectorItem*)i )->file() ); + emit closeMe(); +} + +void ImageFileSelector::thumbClicked(const DocLnk &f) +{ + emit fileSelected( f ); + emit closeMe(); +} + diff --git a/noncore/unsupported/showimg/ImageFileSelector.h b/noncore/unsupported/showimg/ImageFileSelector.h new file mode 100644 index 0000000..798ebcc --- a/dev/null +++ b/noncore/unsupported/showimg/ImageFileSelector.h @@ -0,0 +1,134 @@ +#ifndef IMAGEFILE_SELECTOR_H +#define IMAGEFILE_SELECTOR_H + + +#include <qtoolbutton.h> +#include <qlistview.h> +#include <qwidgetstack.h> +#include <qlayout.h> + +#include "qpe/filemanager.h" +#include "qpe/applnk.h" + +class QScrollView; +class QLabel; +//class QValueList; + +class ThumbWidget : public QWidget +{ + Q_OBJECT +public: + ThumbWidget(QPixmap p,QString text,const DocLnk& f,QWidget *parent=0,int width=-1); + ~ThumbWidget() { } + + DocLnk file() const { + return fl; + } + + + signals: + void clicked(const DocLnk &); + +protected: + void paintEvent( QPaintEvent * ); + void resizeEvent(QResizeEvent *); + + void mouseReleaseEvent(QMouseEvent* event); + +private: + QPixmap pixmap; + QLabel *description; + DocLnk fl; +}; + + + + +class ImageFileSelectorItem : public QListViewItem +{ +public: + ImageFileSelectorItem( QListView *parent, const DocLnk& f ); + ~ImageFileSelectorItem(); + + DocLnk file() const { + return fl; + } +private: + DocLnk fl; +}; + +class ImageFileSelector : public QWidgetStack +{ + Q_OBJECT + +public: + + enum CURRENT_VIEW { + THUMBNAIL, + DETAILED, + UNKNOWN + }; + + + ImageFileSelector(CURRENT_VIEW scv=DETAILED, QWidget *parent=0, const char *name=0 ); + ~ImageFileSelector(); + + void reread(bool purgeCache=false); + int fileCount(); + const DocLnk *selected(); + + void setView(CURRENT_VIEW v); + + CURRENT_VIEW view() { + return cView; + } + + QValueList<DocLnk> fileList() const { + ((ImageFileSelector*)this)->fileCount(); // ensure all loaded when this is extended + QValueList<DocLnk> list; + ImageFileSelectorItem *item = (ImageFileSelectorItem *)detailed->firstChild(); + while (item) { + list.append(item->file()); + item = (ImageFileSelectorItem *)item->nextSibling(); + } + return list; + } + +public slots: + + void switchView(); + +signals: + void fileSelected( const DocLnk & ); + void closeMe(); + +protected: + + void resizeEvent(QResizeEvent *); + + +private slots: + void fileClicked( int, QListViewItem *, const QPoint &, int ); + // pressed to get 'right down' + void filePressed( int, QListViewItem *, const QPoint &, int ); + void fileClicked( QListViewItem *); + void thumbClicked(const DocLnk &); + +private: + + void updateSizes(); + + + CURRENT_VIEW cView; + int count; + + QListView *detailed; + QScrollView *thumb; + QList<ThumbWidget> tList; + QWidget *background; + QGridLayout *gl; + +}; +#endif // IMAGEFILE_SELECTOR_H + + diff --git a/noncore/unsupported/showimg/README b/noncore/unsupported/showimg/README new file mode 100644 index 0000000..a6c9ca9 --- a/dev/null +++ b/noncore/unsupported/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/noncore/unsupported/showimg/config.in b/noncore/unsupported/showimg/config.in new file mode 100644 index 0000000..2938269 --- a/dev/null +++ b/noncore/unsupported/showimg/config.in @@ -0,0 +1,4 @@ + config SHOWIMG + boolean "opie-showimg (image viewer)" + default "n" + depends ( LIBQPE || LIBQPE-X11 ) && LIBOPIE2CORE && LIBOPIE2UI diff --git a/noncore/unsupported/showimg/main.cpp b/noncore/unsupported/showimg/main.cpp new file mode 100644 index 0000000..b7ea071 --- a/dev/null +++ b/noncore/unsupported/showimg/main.cpp @@ -0,0 +1,28 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "showimg.h" + + +#include <opie2/oapplicationfactory.h> + +using namespace Opie::Core; +using namespace Opie::Core; +OPIE_EXPORT_APP( OApplicationFactory<ImageViewer> ) diff --git a/noncore/unsupported/showimg/opie-showimg.control b/noncore/unsupported/showimg/opie-showimg.control new file mode 100644 index 0000000..2fbfabc --- a/dev/null +++ b/noncore/unsupported/showimg/opie-showimg.control @@ -0,0 +1,11 @@ +Package: opie-showimg +Files: plugins/application/libshowimg.so* bin/showimg apps/Applications/showimg.desktop pics/imageviewer +Priority: optional +Section: opie/applications +Maintainer: Opie Team <opie@handhelds.org> +Architecture: arm +Depends: task-opie-minimal,libopiecore2, libopieui2 +Description: Image Viewer + The image viewer for the Opie environment. Supports + all graphics formats are compiled into Qt/Embedded (eg. PNG). +Version: $QPE_VERSION$EXTRAVERSION diff --git a/noncore/unsupported/showimg/settingsdialog.cpp b/noncore/unsupported/showimg/settingsdialog.cpp new file mode 100644 index 0000000..202bd0c --- a/dev/null +++ b/noncore/unsupported/showimg/settingsdialog.cpp @@ -0,0 +1,86 @@ +/********************************************************************** +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. +** +** This file is part of the Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "settingsdialog.h" +#include <qslider.h> +#include <qlabel.h> +#include <qcheckbox.h> + +SettingsDialog::SettingsDialog( QWidget *parent, const char *name, bool modal, WFlags f ) + : SettingsDialogBase( parent, name, modal, f ) +{ + connect( delaySlider, SIGNAL(valueChanged(int)), this, SLOT(delayChanged(int)) ); +} + +void SettingsDialog::setDelay( int d ) +{ + delaySlider->setValue( d ); + delayChanged( d ); +} + +int SettingsDialog::delay() const +{ + return delaySlider->value(); +} + +void SettingsDialog::setRepeat( bool r ) +{ + repeatCheck->setChecked( r ); +} + +bool SettingsDialog::repeat() const +{ + return repeatCheck->isChecked(); +} + +void SettingsDialog::delayChanged( int d ) +{ + delayText->setText( QString::number( d ) + " s" ); +} + +void SettingsDialog::setReverse(bool r) +{ + reverseCheck->setChecked(r); +} + +bool SettingsDialog::reverse() const +{ + return reverseCheck->isChecked(); +} + +void SettingsDialog::setRotate(bool r) +{ + rotateCheck->setChecked(r); +} + +bool SettingsDialog::rotate() const +{ + return rotateCheck->isChecked(); +} + +void SettingsDialog::setFastLoad(bool f) +{ + fastLoadCheck->setChecked(f); +} + +bool SettingsDialog::fastLoad() const +{ + return fastLoadCheck->isChecked(); +} diff --git a/noncore/unsupported/showimg/settingsdialog.h b/noncore/unsupported/showimg/settingsdialog.h new file mode 100644 index 0000000..0f47990 --- a/dev/null +++ b/noncore/unsupported/showimg/settingsdialog.h @@ -0,0 +1,49 @@ +/********************************************************************** +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. +** +** This file is part of the Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef SETTINGSDIALOG_H +#define SETTINGSDIALOG_H + +#include "settingsdialogbase.h" + +class SettingsDialog : public SettingsDialogBase +{ + Q_OBJECT +public: + + SettingsDialog( QWidget * parent=0, const char * name=0, bool modal=FALSE, WFlags f=0 ); + + void setDelay( int d ); + int delay() const; + void setRepeat( bool r ); + bool repeat() const; + void setReverse( bool r ); + bool reverse() const; + void setRotate(bool r); + bool rotate() const; + void setFastLoad(bool f); + bool fastLoad() const; + +private slots: + void delayChanged( int ); +}; + + +#endif diff --git a/noncore/unsupported/showimg/settingsdialogbase.cpp b/noncore/unsupported/showimg/settingsdialogbase.cpp new file mode 100644 index 0000000..7a64e89 --- a/dev/null +++ b/noncore/unsupported/showimg/settingsdialogbase.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** +** Form implementation generated from reading ui file 'settingsdialogbase.ui' +** +** Created: Sun Nov 3 07:29:03 2002 +** by: The User Interface Compiler (uic) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ +#include "settingsdialogbase.h" + +#include <qcheckbox.h> +#include <qgroupbox.h> +#include <qlabel.h> +#include <qslider.h> +#include <qlayout.h> + +/* + * Constructs a SettingsDialogBase which is a child of 'parent', with the + * name 'name' and widget flags set to 'f' + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +SettingsDialogBase::SettingsDialogBase( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ) +{ + if ( !name ) + setName( "SettingsDialogBase" ); + resize( 246, 201 ); + setCaption( tr( "Preferences" ) ); + SettingsDialogBaseLayout = new QVBoxLayout( this ); + SettingsDialogBaseLayout->setSpacing( 6 ); + SettingsDialogBaseLayout->setMargin( 6 ); + + GroupBox1 = new QGroupBox( this, "GroupBox1" ); + GroupBox1->setTitle( tr( "Slide Show" ) ); + GroupBox1->setColumnLayout(0, Qt::Vertical ); + GroupBox1->layout()->setSpacing( 0 ); + GroupBox1->layout()->setMargin( 0 ); + GroupBox1Layout = new QVBoxLayout( GroupBox1->layout() ); + GroupBox1Layout->setAlignment( Qt::AlignTop ); + GroupBox1Layout->setSpacing( 6 ); + GroupBox1Layout->setMargin( 11 ); + + Layout3 = new QGridLayout; + Layout3->setSpacing( 6 ); + Layout3->setMargin( 0 ); + + TextLabel1 = new QLabel( GroupBox1, "TextLabel1" ); + TextLabel1->setText( tr( "Delay between pictures" ) ); + + Layout3->addMultiCellWidget( TextLabel1, 0, 0, 0, 1 ); + + delaySlider = new QSlider( GroupBox1, "delaySlider" ); + delaySlider->setMinValue( 2 ); + delaySlider->setMaxValue( 60 ); + delaySlider->setLineStep( 2 ); + delaySlider->setOrientation( QSlider::Horizontal ); + delaySlider->setTickmarks( QSlider::Right ); + delaySlider->setTickInterval( 10); + + Layout3->addWidget( delaySlider, 1, 0 ); + + delayText = new QLabel( GroupBox1, "delayText" ); + delayText->setMinimumSize( QSize( 25, 0 ) ); + delayText->setText( tr( "s" ) ); + delayText->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignRight ) ); + + Layout3->addWidget( delayText, 1, 1 ); + GroupBox1Layout->addLayout( Layout3 ); + + repeatCheck = new QCheckBox( GroupBox1, "repeatCheck" ); + repeatCheck->setText( tr( "Repeat slideshow" ) ); + GroupBox1Layout->addWidget( repeatCheck ); + + reverseCheck = new QCheckBox( GroupBox1, "reverseCheck" ); + reverseCheck->setText( tr( "Show pictures in reverse" ) ); + GroupBox1Layout->addWidget( reverseCheck ); + SettingsDialogBaseLayout->addWidget( GroupBox1 ); + + rotateCheck = new QCheckBox( this, "rotateCheck" ); + rotateCheck->setText( tr( "Load pictures rotated 90 degrees" ) ); + SettingsDialogBaseLayout->addWidget( rotateCheck ); + + fastLoadCheck = new QCheckBox( this, "fastLoadCheck" ); + fastLoadCheck->setText( tr( "Fast load pictures" ) ); + SettingsDialogBaseLayout->addWidget( fastLoadCheck ); + fastLoadCheck->hide(); //FIXME +// QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding ); +// layout->addItem( spacer, 10, 0 ); + + +} + +/* + * Destroys the object and frees any allocated resources + */ +SettingsDialogBase::~SettingsDialogBase() +{ + // no need to delete child widgets, Qt does it all for us +} + diff --git a/noncore/unsupported/showimg/settingsdialogbase.h b/noncore/unsupported/showimg/settingsdialogbase.h new file mode 100644 index 0000000..9594ec6 --- a/dev/null +++ b/noncore/unsupported/showimg/settingsdialogbase.h @@ -0,0 +1,45 @@ +/**************************************************************************** +** Form interface generated from reading ui file 'settingsdialogbase.ui' +** +** Created: Sun Nov 3 07:29:03 2002 +** by: The User Interface Compiler (uic) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ +#ifndef SETTINGSDIALOGBASE_H +#define SETTINGSDIALOGBASE_H + +#include <qvariant.h> +#include <qdialog.h> +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QCheckBox; +class QGroupBox; +class QLabel; +class QSlider; + +class SettingsDialogBase : public QDialog +{ + Q_OBJECT + +public: + SettingsDialogBase( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~SettingsDialogBase(); + + QGroupBox* GroupBox1; + QLabel* TextLabel1; + QSlider* delaySlider; + QLabel* delayText; + QCheckBox* repeatCheck; + QCheckBox* reverseCheck; + QCheckBox* rotateCheck; + QCheckBox* fastLoadCheck; + +protected: + QVBoxLayout* SettingsDialogBaseLayout; + QVBoxLayout* GroupBox1Layout; + QGridLayout* Layout3; +}; + +#endif // SETTINGSDIALOGBASE_H diff --git a/noncore/unsupported/showimg/showimg.cpp b/noncore/unsupported/showimg/showimg.cpp new file mode 100644 index 0000000..24377ed --- a/dev/null +++ b/noncore/unsupported/showimg/showimg.cpp @@ -0,0 +1,1242 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +// +// Full-screen and rotation options contributed by Robert Wittams <robert@wittams.com> +// + +#include "showimg.h" +#include "ImageFileSelector.h" +#include "settingsdialog.h" + +/* OPIE */ +#include <opie2/odebug.h> +#include <opie2/ofiledialog.h> +#include <qpe/qpeapplication.h> +#include <qpe/config.h> +#include <qpe/resource.h> +using namespace Opie::Core; +using namespace Opie::Ui; + +/* QT */ +#include <qtoolbar.h> +#include <qaction.h> +#include <qfiledialog.h> +#include <qmenubar.h> +#include <qspinbox.h> + +/* STD */ +#include <math.h> + +ControlsDialog::ControlsDialog(const QString &caption,QImage image,int *brightness,QWidget *parent) + : QDialog(parent,0,true) +{ + setCaption(caption); + + if ( parent ) { + setPalette(parent->palette()); + } + + b=brightness; + img=image; + + setMinimumSize(140,80); + + QGridLayout *gl= new QGridLayout(this,2,2,4,4); + + pixmap =new ImageWidget(this);; + QPixmap pm; + pm.convertFromImage(img); + pixmap->setPixmap(pm); + pixmap->setMinimumSize(pm.width(),pm.height()); + gl->addMultiCellWidget(pixmap,0,0,0,2,AlignCenter); + QLabel *l=new QLabel(tr("Brightness")+":",this); + gl->addWidget(l,1,0,AlignLeft); + spb=new QSpinBox(-100,100,2,this); + gl->addWidget(spb,1,1,AlignRight); + + spb->setValue(0); + + connect(spb,SIGNAL(valueChanged(int)),this, SLOT(bValueChanged(int))); + +} + +void ControlsDialog::bValueChanged(int value) +{ + QImage nImage=img; + nImage.detach(); + ImageViewer::intensity(nImage, (float)value/100); + QPixmap pm; + pm.convertFromImage(nImage); + pixmap->setPixmap(pm); + pixmap->repaint(false); + + +} + +void ControlsDialog::accept() +{ + *b=spb->value(); + done(1); +} + +//=========================================================================== + +InfoDialog::InfoDialog(const QString &caption, const QStringList text,QWidget *parent) + : QDialog(parent,0,true) +{ + setCaption(caption); + + if ( parent ) + { + setPalette(parent->palette()); + } + + + + QString labels[]={ tr("File Name"),tr("Format"),tr("File Size"),tr("Size"),tr("Colors"),tr("Alpha") }; + + setMinimumSize(180,80); + int num=ImageViewer::LAST+1; + if ( text[ImageViewer::ALPHA].isEmpty() ) + num--; + QGridLayout *gl= new QGridLayout(this,num,2,4,2); + QLabel *l; + int count=0; + for ( int i=0;i<num;i++ ) + { + if ( i==1 ) + { + QFrame *frm=new QFrame(this); + frm->setFrameStyle(QFrame::HLine|QFrame::Sunken); + gl->addMultiCellWidget(frm,i,i,0,1); + } + else + { + l=new QLabel( tr( labels[count] )+":",this); + gl->addWidget(l,i,0,AlignLeft); + l=new QLabel(text[count],this); + gl->addWidget(l,i,1,AlignRight); + count++; + } + + } + +} + +void InfoDialog::displayInfo(const QString &caption, const QStringList text, QWidget *parent) +{ + InfoDialog *dlg=new InfoDialog(caption,text,parent); + dlg->exec(); + delete dlg; +} + +//=========================================================================== + + +ImagePane::ImagePane( QWidget *parent ) : QWidget( parent ) +{ + vb = new QVBoxLayout( this ); + + image = new QScrollView(this,0,WResizeNoErase|WNorthWestGravity); + pic=new ImageWidget(image); + image->addChild(pic); + + connect(pic, SIGNAL( clicked() ), this, SLOT( imageClicked() )); + + vb->addWidget( image ); + +} + +void ImagePane::setPixmap( const QPixmap &pm ) +{ + pic->setPixmap( pm ); + pic->resize(pm.width(),pm.height()); + image->updateScrollBars (); + pic->repaint(false); +} + +void ImagePane::imageClicked() +{ + emit clicked(); +} +//=========================================================================== +/* + Draws the portion of the scaled pixmap that needs to be updated +*/ + +void ImageWidget::paintEvent( QPaintEvent *e ) +{ + QPainter painter(this); + + painter.setClipRect(e->rect()); + painter.fillRect(0,0,width(),height(),QColor(0,0,0)); + + if ( pixmap.size() != QSize( 0, 0 ) ) + { // is an image loaded? + painter.drawPixmap((width() - pixmap.width()) / 2, (height() - pixmap.height()) / 2, pixmap); + } +} + +void ImageWidget::mouseReleaseEvent(QMouseEvent *) +{ + emit clicked(); +} + +//=========================================================================== + +ImageViewer::ImageViewer( QWidget *parent, const char *name, int /*wFlags*/ ) +: QMainWindow( parent, name, WResizeNoErase ), filename( 0 ), bFromDocView( FALSE ) +{ + setCaption( tr("Image Viewer") ); + setIcon( Resource::loadPixmap( "ImageViewer" ) ); + + + Config cfg("Image Viewer"); + cfg.setGroup("Image Viewer"); + + showThumbView=cfg.readBoolEntry("ShowThumbnails",false); + isSized=cfg.readBoolEntry("SizeToScreen",true); + + isFullScreen = FALSE; + + setToolBarsMovable( FALSE ); + + toolBar = new QToolBar( this ); + toolBar->setHorizontalStretchable( TRUE ); + + menuBar = new QMenuBar( toolBar ); + + current=menuBar; + + + + fileMenuFile = new QPopupMenu(this); + //menuBarmenubarFile->insertItem( tr("File"), fileMenu ); + fileMenuFile->insertItem(tr("Open"), + this, SLOT(openFile()), 0); + + viewMenuFile = new QPopupMenu( this ); + //menubarFile->insertItem( tr("View"), viewMenu ); + viewMenuFile->insertItem( tr("Thumbnail View"), + this, SLOT(switchThumbView()), 0, SHOW_THUMBNAILS ); + + viewMenuFile->setItemChecked ( SHOW_THUMBNAILS, showThumbView ); + + + + + optionsMenuFile = new QPopupMenu( this); + //menubarFile->insertItem( tr("Options"),optionsMenu ); + slideAction = new QAction( tr( "Slide show" ), Resource::loadIconSet( "slideshow" ), + QString::null, 0, this, 0 ); + slideAction->setToggleAction( TRUE ); + connect( slideAction, SIGNAL( toggled(bool) ), this, SLOT( slideShow(bool) ) ); + slideAction->addTo( optionsMenuFile); +// slideAction->addTo( toolBar ); + + +// optionsMenuFile->insertItem( tr("Slideshow") ); + optionsMenuFile->insertSeparator(); + optionsMenuFile->insertItem( tr("Preferences.."), this, SLOT(settings()), 0); +// optionsMenuFile->insertItem( tr("Help"), this, SLOT(help()), 0); + + QStrList fmt = QImage::outputFormats(); + + + fileMenuView = new QPopupMenu( this ); + //menubarView->insertItem( tr("File"),fileMenu ); + fileMenuView->insertItem( tr("Image Info ..."),this, SLOT(displayInfoDialog()),0 ); + fileMenuView->insertSeparator(); + + viewMenuView = new QPopupMenu(this ); + viewMenuView->setCheckable ( true ); + + //menubarView->insertItem( tr("View"),viewMenu ); + viewMenuView->insertItem(tr("Horizontal flip"), this, SLOT(hFlip()), 0); + viewMenuView->insertItem(tr("Vertical flip"), this, SLOT(vFlip()), 0); + + stack = new QWidgetStack( this ); + stack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); + setCentralWidget( stack ); + + + imagePanel = new ImagePane( stack ); + connect(imagePanel, SIGNAL(clicked()), this, SLOT(normalView())); + + + ImageFileSelector::CURRENT_VIEW cv; + if(showThumbView) + cv=ImageFileSelector::THUMBNAIL; + else + cv=ImageFileSelector::DETAILED; + + odebug << "cv = " << cv << "" << oendl; + + fileSelector = new ImageFileSelector( cv,stack, "fs"); + + //switchThumbView(); + + + //fileSelector = new ImageFileSelector("image/*", stack, "fs"); + //fileSelector->setNewVisible(FALSE); + //fileSelector->setCloseVisible(FALSE); + connect( fileSelector, SIGNAL( closeMe() ), this, SLOT( closeFileSelector() ) ); + connect( fileSelector, SIGNAL( fileSelected(const DocLnk&) ), + this, SLOT( openFile(const DocLnk&) ) ); + + imageList = fileSelector->fileList(); + slideAction->setEnabled( imageList.count() != 0); + + iconToolBar = new QToolBar(this); + + QAction *a; + + a = new QAction( tr( "Open ..." ), Resource::loadPixmap( "fileopen" ), QString::null, 0, this, 0 ); + connect( a, SIGNAL( activated() ), this, SLOT( open() ) ); + a->addTo( fileMenuView); + a->addTo( iconToolBar ); + + + a = new QAction( tr( "Rotate 90"), Resource::loadPixmap( "rotate90" ), QString::null, 0, this, 0); + connect( a, SIGNAL( activated() ), this, SLOT( rot90() ) ); + a->addTo( iconToolBar ); + a->addTo( viewMenuView ); + + a = new QAction( tr( "Rotate 180" ), Resource::loadPixmap( "repeat" ), QString::null, 0, this, 0 ); + connect( a, SIGNAL( activated() ), this, SLOT( rot180() ) ); + a->addTo( iconToolBar ); + a->addTo( viewMenuView ); + + + a = new QAction( tr( "Rotate 270"), Resource::loadPixmap( "rotate270" ), QString::null, 0, this, 0); + connect( a, SIGNAL( activated() ), this, SLOT( rot270() ) ); + //a->addTo( iconToolBar ); + a->addTo( viewMenuView ); + + + + viewMenuView->insertSeparator(); + viewMenuView->insertItem(tr("Brightness ..."), this, SLOT(displayControlsDialog()), 0); + viewMenuView->insertItem(tr("Black And White"), this, SLOT(blackAndWhite()), 0,BLACKANDWHITE); + viewMenuView->insertSeparator(); + + + sss = new QAction( tr( "Scale to Screen"), Resource::loadPixmap( "scale" ), QString::null, 0, this, 0,true); + connect( sss, SIGNAL( activated() ), this, SLOT( switchSizeToScreen() ) ); + sss->addTo( iconToolBar ); + sss->addTo( viewMenuView ); + + sss->setOn(isSized); + viewMenuView->insertSeparator(); + + + a = new QAction( tr( "Fullscreen" ), Resource::loadPixmap( "fullscreen" ), + QString::null, 0, this, 0 ); + connect( a, SIGNAL( activated() ), this, SLOT( fullScreen() ) ); + a->addTo( iconToolBar ); + a->addTo( viewMenuView); + + a = new QAction( tr( "Stop Slideshow" ), Resource::loadPixmap( "quit_icon" ), + QString::null, 0, this, 0 ); + connect( a, SIGNAL( activated() ), this, SLOT( stopSlideShow() ) ); + a->addTo( iconToolBar ); + a->addTo( viewMenuView); + + + Config config( "ImageViewer" ); + config.setGroup( "SlideShow" ); + slideDelay = config.readNumEntry( "Delay", 2); + slideRepeat = config.readBoolEntry( "Repeat", FALSE ); + slideReverse = config.readBoolEntry("Reverse", FALSE); + + config.setGroup("Default"); + rotateOnLoad = config.readBoolEntry("Rotate", FALSE); + fastLoad = config.readBoolEntry("FastLoad", TRUE); + slideTimer = new QTimer( this ); + connect( slideTimer, SIGNAL(timeout()), this, SLOT(slideUpdate()) ); + + switchToFileSelector(); + + setMouseTracking( TRUE ); + + +} + +ImageViewer::~ImageViewer() +{ + Config cfg("Image Viewer"); + cfg.setGroup("Image Viewer"); + + cfg.writeEntry("ShowThumbnails",(int)showThumbView); + cfg.writeEntry("SizeToScreen",(int)isSized); + + cfg.setGroup( "SlideShow" ); + cfg.writeEntry( "Delay", slideDelay); + cfg.writeEntry( "Repeat", slideRepeat ); + cfg.writeEntry("Reverse", slideReverse); + + cfg.setGroup("Default"); + cfg.writeEntry("Rotate", rotateOnLoad); + cfg.writeEntry("FastLoad", fastLoad); + + delete imagePanel; // in case it is fullscreen +} + +void ImageViewer::help() { + +} + + +void ImageViewer::settings() +{ + SettingsDialog dlg( this, 0, TRUE ); + dlg.setDelay( slideDelay ); + dlg.setRepeat( slideRepeat ); + dlg.setReverse( slideReverse ); + dlg.setRotate(rotateOnLoad); + dlg.setFastLoad(fastLoad); + + if ( QPEApplication::execDialog(&dlg) == QDialog::Accepted ) { + odebug << "<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>" << oendl; + slideDelay = dlg.delay(); + slideRepeat = dlg.repeat(); + slideReverse = dlg.reverse(); + rotateOnLoad = dlg.rotate(); + fastLoad = dlg.fastLoad(); + + Config config( "ImageViewer" ); + config.setGroup( "SlideShow" ); + config.writeEntry( "Delay", slideDelay ); + config.writeEntry( "Repeat", slideRepeat ); + config.writeEntry("Reverse", slideReverse); + + config.setGroup("Default"); + config.writeEntry("Rotate", rotateOnLoad); + config.writeEntry("FastLoad", fastLoad); + } +} + +void ImageViewer::switchSizeToScreen() +{ + isSized=!isSized; + sss->setOn(isSized); + updateImage(); +} + +void ImageViewer::updateImage() +{ + if ( isSized ) { + imagePanel->setPixmap(pmScaled); + } else { + imagePanel->setPixmap(pm); + } +} + +void ImageViewer::switchThumbView() +{ + + showThumbView=!showThumbView; + viewMenuFile->setItemChecked ( SHOW_THUMBNAILS, showThumbView ); + fileSelector->switchView(); + +} + +void ImageViewer::switchToFileSelector() +{ + stack->raiseWidget(fileSelector); + menuBar->clear(); + menuBar->insertItem( tr("File"), fileMenuFile ); + menuBar->insertItem( tr("View"), viewMenuFile ); + menuBar->insertItem( tr("Options"), optionsMenuFile ); + iconToolBar->hide(); + imagePanel->disable(); + slideShow(false); + +} + +void ImageViewer::switchToImageView() +{ + stack->raiseWidget(imagePanel); + + menuBar->clear(); + menuBar->insertItem( tr("File"), fileMenuView ); + menuBar->insertItem( tr("View"), viewMenuView ); + viewMenuView->setItemEnabled(BLACKANDWHITE,true); + iconToolBar->show(); + + imagePanel->setPosition(0,0); + +} + + +void ImageViewer::setDocument(const QString& fileref) +{ + delayLoad = fileref; + switchToImageView(); + QTimer::singleShot( 0, this, SLOT(doDelayedLoad()) ); +} + +void ImageViewer::doDelayedLoad() +{ + show(delayLoad); +} + +void ImageViewer::show() +{ + normalView(); + QMainWindow::show(); +} + +void ImageViewer::show(const QString& fileref) +{ +// odebug << "Show "+fileref << oendl; + bFromDocView = TRUE; + closeFileSelector(); + DocLnk link(fileref); + if ( link.isValid() ) { + openFile(link); + } else { + filename = fileref; + updateCaption( fileref ); + loadImage( fileref ); + } +} + +void ImageViewer::openFile() { + MimeTypes types; + QStringList image; + image << "image/*"; + types.insert("Images", image); + + QString str = OFileDialog::getOpenFileName( 1,QPEApplication::documentDir(),"", types, 0 ); + DocLnk link(str); +// if ( link.isValid() ) + openFile(link); + +} + +void ImageViewer::openFile( const DocLnk &link ) +{ + closeFileSelector(); +// DocLnk link(file); + odebug << "open "+link.name() << oendl; + updateCaption( link.name() ); + loadImage( link.file() ); + if (slideTimer->isActive()) { + slideTimer->start(slideDelay * 1000, FALSE); + } + +} + +void ImageViewer::open() +{ + switchToFileSelector(); +} + +void ImageViewer::closeFileSelector() +{ + switchToImageView(); +} + +void ImageViewer::updateCaption( QString name ) +{ + int sep = name.findRev( '/' ); + if ( sep >= 0 ) + name = name.mid( sep+1 ); + setCaption( name + tr(" - Image Viewer") ); +} + +/* + This function loads an image from a file. +*/ + +void ImageViewer::loadImage( const char *fileName ) +{ + filename = fileName; + if ( filename ) { + QApplication::setOverrideCursor( waitCursor ); // this might take time + //imagePanel->statusLabel()->setText( tr("Loading image...") ); + qApp->processEvents(); + bool ok = image.load(filename, 0); + if ( ok ) { + ok = reconvertImage(); + updateImageInfo(filename); + } + if ( !ok ) { + pm.resize(0,0); // couldn't load image + update(); + } + QApplication::restoreOverrideCursor(); // restore original cursor + } + +// fastLoad ? ", Fast" : "", +// fastLoad ? QMAX(imagewidth/maxsize, imageheight/maxsize) : 1); + + +// matrix.reset(); + rotated90 = FALSE; + + if (rotateOnLoad) { + rotated90 = TRUE; + rot90(); +// matrix.rotate( -90.0 ); + } + + switchToImageView(); + updateImage(); + +} + +bool ImageViewer::loadSelected() +{ + bool ok = false; + if ( stack->visibleWidget() == fileSelector ) + { + const DocLnk *link = fileSelector->selected(); + if ( link ) + { + if ( link->file() != filename ) + { + updateCaption( link->name() ); + filename = link->file(); + qApp->processEvents(); + ok = image.load(filename, 0); + if ( ok ) + { + updateImageInfo(filename); + ok = reconvertImage(); + } + if ( !ok ) + pm.resize(0,0); + } + } + } + if ( !image.isNull() ) + { + ok = true; + closeFileSelector(); + } + + return ok; +} + +bool ImageViewer::reconvertImage() +{ + bool success = FALSE; + + if ( image.isNull() ) return FALSE; + + QApplication::setOverrideCursor( waitCursor ); // this might take time + if ( pm.convertFromImage(image /*, conversion_flags */ ) ) + { + pmScaled = QPixmap(); + scale(); + success = TRUE; // load successful + } + else + { + pm.resize(0,0); // couldn't load image + } + QApplication::restoreOverrideCursor(); // restore original cursor + + return success; // TRUE if loaded OK +} + + +int ImageViewer::calcHeight() +{ + if ( !isFullScreen ) + return imagePanel->paneHeight(); + else + return qApp->desktop()->height(); +} +/* + 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 = calcHeight(); + if ( image.isNull() ) return; + + QApplication::setOverrideCursor( waitCursor ); // this might take time + if ( imagePanel->paneWidth() == pm.width() && h == pm.height() ) + { // no need to scale if widget + pmScaled = pm; // size equals pixmap size + } + else + { + double hs = (double)h / (double)image.height(); + double ws = (double)imagePanel->paneWidth() / (double)image.width(); + double scaleFactor = (hs > ws) ? ws : hs; + int smoothW = (int)(scaleFactor * image.width()); + int smoothH = (int)(scaleFactor * image.height()); + + pmScaled.convertFromImage( image.smoothScale( smoothW, smoothH ) /*, conversion_flags */ ); + } + 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 * ) +{ + + if ( pm.size() == QSize( 0, 0 ) ) // we couldn't load the image + return; + + int h = calcHeight(); + + if ( imagePanel->paneWidth() != pmScaled.width() || h != pmScaled.height() ) + { // if new size, + scale(); // scale pmScaled to window + } + if ( image.hasAlphaBuffer() ) + erase(); +} + + +void ImageViewer::hFlip() +{ +// matrix.scale( -1.0, 1.0 ); + + setImage(image.mirror(TRUE,FALSE)); +} + +void ImageViewer::vFlip() +{ +// matrix.scale( 1.0, -1.0 ); + setImage(image.mirror(FALSE,TRUE)); +} + +void ImageViewer::rot180() +{ +// matrix.rotate( 180.0 ); + setImage(image.mirror(TRUE,TRUE)); +} + +void ImageViewer::rot90() +{ + QImage oldimage; + oldimage = image.convertDepth(32); +// matrix.rotate( -90.0 ); + setImage(rotate(oldimage,Rotate90)); + +} +void ImageViewer::rot270() +{ + + QImage oldimage; + oldimage = image.convertDepth(32); +// matrix.rotate(90.0); + setImage(rotate(oldimage,Rotate270)); + +} + +void ImageViewer::blackAndWhite() +{ + + viewMenuView->setItemEnabled(BLACKANDWHITE,false); + setImage(toGray(image,false)); +} + +void ImageViewer::displayControlsDialog() +{ + int w=80; + int h=w; + QImage small; + + if ( image.width()<w ||image.height()<h ) + small=image.smoothScale(w,h); + else + small=image.copy(0,0,w,h); + + int newB=0; + ControlsDialog *dlg=new ControlsDialog("Image Viewer",small,&newB,this); + dlg->exec(); + if ( newB ) { + intensity(image,(float)newB/100); + setImage(image); + } + +} + + +void ImageViewer::displayInfoDialog() +{ + + QStringList ls; + + for ( int i=0;i<LAST;i++ ) + ls.append(imageInfo[i]); + + InfoDialog::displayInfo("Image Viewer",ls,this); +} +void ImageViewer::normalView() +{ + if ( !imagePanel->parentWidget() ) + { + + isFullScreen = FALSE; + stack->addWidget( imagePanel, 1 ); + switchToImageView(); + if ( isSized ) + scale(); + + updateImage(); + + } +} + +void ImageViewer::stopSlideShow() { + if (slideTimer->isActive()) + slideTimer->stop(); +} + +void ImageViewer::fullScreen() +{ + // Full-screen option + // contributed by Robert Wittams <robert@wittams.com> + if ( imagePanel->parentWidget() && loadSelected() ) + { + isFullScreen = TRUE; + imagePanel->reparent(0,QPoint(0,0)); + imagePanel->resize(qApp->desktop()->width(), qApp->desktop()->height()); + + if ( isSized ) + scale(); + updateImage(); + imagePanel->showFullScreen(); + } +} + +void ImageViewer::setImage(const QImage& newimage) +{ + image = newimage; + reconvertImage(); + updateImage(); +} + +void ImageViewer::updateImageInfo(QString &filePath) +{ + + for ( int i=0;i<LAST;i++ ) + { + imageInfo[i]=""; + } + + imageInfo[FORMAT]=QImage::imageFormat (filePath ); + QFileInfo fi(filePath); + imageInfo[PATH]=fi.fileName(); + imageInfo[FILE_SIZE]=QString::number(fi.size())+" (bytes)"; + QString message("%1x%2"); + imageInfo[SIZE]=QString("%1x%2"); + imageInfo[SIZE]=imageInfo[SIZE].arg(image.width()).arg(image.height()); + if ( image.numColors() > 0 ) + { + imageInfo[COLORS]=tr("%1 colors").arg(image.numColors()); + } + else if ( image.depth() >= 16 ) + { + imageInfo[COLORS]=tr(" True color"); + } + 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<image.numColors(); i++ ) + { + int alevel = image.color(i) >> 24; + if ( !alpha[alevel] ) + { + alpha[alevel] = TRUE; + nalpha++; + } + } + imageInfo[ALPHA]=tr("%1 alpha levels").arg(nalpha); + } + else + { + imageInfo[ALPHA]=tr("8-bit alpha channel"); + } + } + +} + +void ImageViewer::closeEvent( QCloseEvent *e ) +{ + if ( stack->visibleWidget() == imagePanel && !bFromDocView ) + { + e->ignore(); + open(); + } + else + { + bFromDocView = FALSE; + e->accept(); + } +} + +// Intensity,toGray and rotate code courtesy of KDE project. + + +QImage& ImageViewer::intensity(QImage &image, float percent) +{ + + int segColors = image.depth() > 8 ? 256 : image.numColors(); + unsigned char *segTbl = new unsigned char[segColors]; + int pixels = image.depth() > 8 ? image.width()*image.height() : + image.numColors(); + unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() : + (unsigned int *)image.colorTable(); + + bool brighten = (percent >= 0); + if ( percent < 0 ) + percent = -percent; + + if ( brighten ) + { // keep overflow check out of loops + for ( int i=0; i < segColors; ++i ) + { + int tmp = (int)(i*percent); + if ( tmp > 255 ) + tmp = 255; + segTbl[i] = tmp; + } + } + else + { + for ( int i=0; i < segColors; ++i ) + { + int tmp = (int)(i*percent); + if ( tmp < 0 ) + tmp = 0; + segTbl[i] = tmp; + } + } + + if ( brighten ) + { // same here + for ( int i=0; i < pixels; ++i ) + { + int r = qRed(data[i]); + int g = qGreen(data[i]); + int b = qBlue(data[i]); + int a = qAlpha(data[i]); + r = r + segTbl[r] > 255 ? 255 : r + segTbl[r]; + g = g + segTbl[g] > 255 ? 255 : g + segTbl[g]; + b = b + segTbl[b] > 255 ? 255 : b + segTbl[b]; + data[i] = qRgba(r, g, b,a); + } + } + else + { + for ( int i=0; i < pixels; ++i ) + { + int r = qRed(data[i]); + int g = qGreen(data[i]); + int b = qBlue(data[i]); + int a = qAlpha(data[i]); + r = r - segTbl[r] < 0 ? 0 : r - segTbl[r]; + g = g - segTbl[g] < 0 ? 0 : g - segTbl[g]; + b = b - segTbl[b] < 0 ? 0 : b - segTbl[b]; + data[i] = qRgba(r, g, b, a); + } + } + delete [] segTbl; + + return image; +} + +QImage& ImageViewer::toGray(QImage &img, bool fast) +{ + if ( img.width() == 0 || img.height() == 0 ) + return img; + + if ( fast ) + { + if ( img.depth() == 32 ) + { + register uchar * r(img.bits()); + register uchar * g(img.bits() + 1); + register uchar * b(img.bits() + 2); + + uchar * end(img.bits() + img.numBytes()); + + while ( r != end ) + { + + *r = *g = *b = (((*r + *g) >> 1) + *b) >> 1; // (r + b + g) / 3 + + r += 4; + g += 4; + b += 4; + } + } + else + { + for ( int i = 0; i < img.numColors(); i++ ) + { + register uint r = qRed(img.color(i)); + register uint g = qGreen(img.color(i)); + register uint b = qBlue(img.color(i)); + + register uint gray = (((r + g) >> 1) + b) >> 1; + img.setColor(i, qRgba(gray, gray, gray, qAlpha(img.color(i)))); + } + } + } + else + { + int pixels = img.depth() > 8 ? img.width()*img.height() : + img.numColors(); + unsigned int *data = img.depth() > 8 ? (unsigned int *)img.bits() : + (unsigned int *)img.colorTable(); + int val, i; + for ( i=0; i < pixels; ++i ) + { + val = qGray(data[i]); + data[i] = qRgba(val, val, val, qAlpha(data[i])); + } + } + return img; +} + + +QImage ImageViewer::rotate(QImage &img, RotateDirection r) +{ + QImage dest; + int x, y; + if ( img.depth() > 8 ) + { + unsigned int *srcData, *destData; + switch ( r ) + { + case Rotate90: + dest.create(img.height(), img.width(), img.depth()); + for ( y=0; y < img.height(); ++y ) + { + srcData = (unsigned int *)img.scanLine(y); + for ( x=0; x < img.width(); ++x ) + { + destData = (unsigned int *)dest.scanLine(x); + destData[img.height()-y-1] = srcData[x]; + } + } + break; + case Rotate180: + dest.create(img.width(), img.height(), img.depth()); + for ( y=0; y < img.height(); ++y ) + { + srcData = (unsigned int *)img.scanLine(y); + destData = (unsigned int *)dest.scanLine(img.height()-y-1); + for ( x=0; x < img.width(); ++x ) + destData[img.width()-x-1] = srcData[x]; + } + break; + case Rotate270: + dest.create(img.height(), img.width(), img.depth()); + for ( y=0; y < img.height(); ++y ) + { + srcData = (unsigned int *)img.scanLine(y); + for ( x=0; x < img.width(); ++x ) + { + destData = (unsigned int *)dest.scanLine(img.width()-x-1); + destData[y] = srcData[x]; + } + } + break; + default: + dest = img; + break; + } + } + else + { + unsigned char *srcData, *destData; + unsigned int *srcTable, *destTable; + switch ( r ) + { + case Rotate90: + dest.create(img.height(), img.width(), img.depth()); + dest.setNumColors(img.numColors()); + srcTable = (unsigned int *)img.colorTable(); + destTable = (unsigned int *)dest.colorTable(); + for ( x=0; x < img.numColors(); ++x ) + destTable[x] = srcTable[x]; + for ( y=0; y < img.height(); ++y ) + { + srcData = (unsigned char *)img.scanLine(y); + for ( x=0; x < img.width(); ++x ) + { + destData = (unsigned char *)dest.scanLine(x); + destData[img.height()-y-1] = srcData[x]; + } + } + break; + case Rotate180: + dest.create(img.width(), img.height(), img.depth()); + dest.setNumColors(img.numColors()); + srcTable = (unsigned int *)img.colorTable(); + destTable = (unsigned int *)dest.colorTable(); + for ( x=0; x < img.numColors(); ++x ) + destTable[x] = srcTable[x]; + for ( y=0; y < img.height(); ++y ) + { + srcData = (unsigned char *)img.scanLine(y); + destData = (unsigned char *)dest.scanLine(img.height()-y-1); + for ( x=0; x < img.width(); ++x ) + destData[img.width()-x-1] = srcData[x]; + } + break; + case Rotate270: + dest.create(img.height(), img.width(), img.depth()); + dest.setNumColors(img.numColors()); + srcTable = (unsigned int *)img.colorTable(); + destTable = (unsigned int *)dest.colorTable(); + for ( x=0; x < img.numColors(); ++x ) + destTable[x] = srcTable[x]; + for ( y=0; y < img.height(); ++y ) + { + srcData = (unsigned char *)img.scanLine(y); + for ( x=0; x < img.width(); ++x ) + { + destData = (unsigned char *)dest.scanLine(img.width()-x-1); + destData[y] = srcData[x]; + } + } + break; + default: + dest = img; + break; + } + + } + return (dest); +} + +void ImageViewer::slideShow( bool on ) +{ + if (on) { + if (!imageList.isEmpty()) { + slideTimer->start(slideDelay * 1000, FALSE); + filename = ""; // force restart + slideReverse ? prevImage() : nextImage(); + } + } else { + slideTimer->stop(); + slideAction->setOn( false); + } +} + +void ImageViewer::slideUpdate() +{ + bool final_image = slideReverse ? prevImage() : nextImage(); + + if (final_image && !slideRepeat) { + slideTimer->stop(); + slideAction->setOn(FALSE); + } +} + +// +// Display the image after the current one in the image list. +// Return TRUE if the next call to nextImage() will wrap around to the +// first image in the list (ie. we're now viewing the last image in the list). +// +bool ImageViewer::nextImage(void) +{ + int idx = 0; + + if (imageList.count() > 0) { + idx = imageIndex(); + if (idx != -1) { + if (idx == int(imageList.count() - 1)) { + idx = 0; + } else { + idx++; + } + } else { + idx = 0; + } + openFile(imageList[idx]); + } + + return idx == int(imageList.count() - 1) ? TRUE : FALSE; +} + +// +// Display the image preceeding the current one in the image list. +// Return TRUE if the next call to prevImage() will wrap around to the last +// image in the list (ie. we're now viewing the first image in the list). +// +bool ImageViewer::prevImage(void) +{ + int idx = -1; + + if (imageList.count() > 0) { + idx = imageIndex(); + if (idx != -1) { + if (idx == 0) { + idx = imageList.count() - 1; + } else { + idx--; + } + } else { + idx = imageList.count() - 1; + } + openFile(imageList[idx]); + } + + return idx == 0 ? TRUE : FALSE; +} + +// +// Return the index into the imageList of the currently viewed +// image (ie. ImageViewer::filename in ImageViewer::imageList). +// +int ImageViewer::imageIndex(void) +{ + QValueListConstIterator<DocLnk> i; + int index; + + if (imageList.count() == 0) { + return -1; + } + + for (index = 0, i = imageList.begin(); i != imageList.end(); ++i, index++) { + if ((*i).file() == filename) { + return index; + } + } + + return -1; +} diff --git a/noncore/unsupported/showimg/showimg.h b/noncore/unsupported/showimg/showimg.h new file mode 100644 index 0000000..9cf9bfd --- a/dev/null +++ b/noncore/unsupported/showimg/showimg.h @@ -0,0 +1,289 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef SHOWIMG_H +#define SHOWIMG_H + +#include <qwidget.h> +#include <qmainwindow.h> +#include <qimage.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qscrollview.h> +#include <qdialog.h> +#include <qstringlist.h> +#include <qvaluelist.h> +#include <qwmatrix.h> + + +class QAction; +class QToolBar; +class QMenuBar; +class QPopupMenu; +class QWidgetStack; +class FileSelector; +class DocLnk; +class QLabel; +class QAction; +class QSpinBox; +class ImageFileSelector; +class QTimer; + + +class ImageWidget : public QWidget +{ + Q_OBJECT + public: + ImageWidget( QWidget *parent=0 ) + : QWidget( parent ) { + setBackgroundMode(NoBackground); + } + ~ImageWidget() { } + + void setPixmap( const QPixmap &pm ) { + pixmap = pm; + show(); + } + +signals: + void clicked(); + +protected: + void paintEvent( QPaintEvent * ); + void mouseReleaseEvent(QMouseEvent* event); + +private: + QPixmap pixmap; +}; + +class InfoDialog:public QDialog +{ + Q_OBJECT + +public: + + static void displayInfo(const QString &caption, const QStringList text, QWidget *parent); + +private: + + InfoDialog(const QString &caption,const QStringList text, QWidget *parent); + +}; + +class ControlsDialog:public QDialog +{ + Q_OBJECT + +public: + ControlsDialog(const QString &caption,const QImage image,int *brightness, QWidget *parent); + + +private slots: + + void bValueChanged(int); + void accept(); + + +private: + ImageWidget *pixmap; + QSpinBox *spb; + QImage img; + int *b; +}; + + +class ImagePane : public QWidget +{ + Q_OBJECT +public: + ImagePane( QWidget *parent=0 ); + ~ImagePane() { } + + //void showStatus(); + //void hideStatus(); + //QLabel *statusLabel() + //{ + // return status; + //} + void setPixmap( const QPixmap &pm ); + + + int paneWidth() const { + return image->visibleWidth(); + } + + int paneHeight() const { + return image->visibleHeight(); + } + + void setPosition(int x, int y) { + image->setContentsPos (x,y ); + } + + void disable() { + pic->hide(); + } + +signals: + void clicked(); + +private: + QScrollView *image; + ImageWidget *pic; + QVBoxLayout *vb; + +private slots: + void imageClicked(); +}; + + +class ImageViewer : public QMainWindow +{ + Q_OBJECT +public: + static QString appName() { return QString::fromLatin1("showimg"); } + ImageViewer( QWidget *parent=0, const char *name=0, int wFlags=0 ); + ~ImageViewer(); + + void loadImage( const char *fileName ); + void show(const QString& fileref); + void show(); + + + enum INFO_STRINGS { + PATH, + FORMAT, + FILE_SIZE, + SIZE, + COLORS, + ALPHA, + LAST + }; + + enum RotateDirection { + Rotate90, Rotate180, Rotate270 + }; + + + static QImage rotate(QImage &img, RotateDirection r); + static QImage& intensity(QImage &image, float percent); + static QImage& toGray(QImage &image, bool fast = false); + bool showThumbView; // a flag to indicate if FileSelector should be initialized with thumbnail view + +protected: + void resizeEvent( QResizeEvent * ); + void closeEvent( QCloseEvent * ); + +private: + int imageIndex(void); + + void updateCaption( QString name ); + bool loadSelected(); + void scale(); + bool reconvertImage(); + int calcHeight(); + void setImage(const QImage& newimage); + void updateImageInfo(QString &filePath); + void switchToFileSelector(); + void switchToImageView(); + + void updateImage(); + +private slots: + + void slideShow( bool on ); + void help(); + void slideUpdate(); + bool nextImage(); + bool prevImage(); + void settings(); + + void switchThumbView(); + void switchSizeToScreen(); + void setDocument(const QString& fileref); + void doDelayedLoad(); + void openFile( const DocLnk &file ); + void openFile(); + void open(); + void closeFileSelector(); + void hFlip(); + void vFlip(); + void rot180(); + void rot90(); + void rot270(); + void normalView(); + void fullScreen(); + void stopSlideShow(); + void blackAndWhite(); + void displayInfoDialog(); + void displayControlsDialog(); +private: + QWMatrix matrix; + bool rotated90; + enum MENU_ITEMS { + SHOW_THUMBNAILS, + SIZE_TO_SCREEN, + BLACKANDWHITE + }; + + QString filename; + QString delayLoad; + QImage image; // the loaded image + QPixmap pm; // the converted pixmap + QPixmap pmScaled; // the scaled pixmap + QToolBar *toolBar; + QToolBar *iconToolBar; + QMenuBar *menuBar; + QMenuBar *current; + + + QPopupMenu *fileMenuFile; + QPopupMenu *viewMenuFile; + QPopupMenu *optionsMenuFile; + QPopupMenu *fileMenuView; + QPopupMenu *viewMenuView; + + QAction *sss; // scale to screen size + + QLabel *lab; + ImagePane *imagePanel; + QWidgetStack *stack; + //FileSelector *fileSelector; + ImageFileSelector *fileSelector; + bool isFullScreen; + bool isSized; // true if image is to be resized to fit the window size + bool bFromDocView; // a flag to indicate whether or not we were + // launched from the document view... + + int slideDelay; + bool slideRepeat; + bool slideReverse; // show slideshow in reverse order + bool rotateOnLoad; // rotate by 90 degrees on loading + bool fastLoad; + QTimer *slideTimer; + QValueList<DocLnk> imageList; + QAction *slideAction; + + + QString imageInfo[LAST]; +}; + + +#endif // SHOWIMG_H diff --git a/noncore/unsupported/showimg/showimg.pro b/noncore/unsupported/showimg/showimg.pro new file mode 100644 index 0000000..74eceb8 --- a/dev/null +++ b/noncore/unsupported/showimg/showimg.pro @@ -0,0 +1,9 @@ +CONFIG += qt warn_on quick-app +HEADERS = showimg.h ImageFileSelector.h settingsdialog.h settingsdialogbase.h +SOURCES = main.cpp showimg.cpp ImageFileSelector.cpp settingsdialog.cpp settingsdialogbase.cpp +TARGET = showimg +INCLUDEPATH += $(OPIEDIR)/include +DEPENDPATH += $(OPIEDIR)/include +LIBS += -lqpe -lopiecore2 -lopieui2 + +include( $(OPIEDIR)/include.pro ) |