-rw-r--r-- | noncore/multimedia/showimg/ImageFileSelector.cpp | 46 | ||||
-rw-r--r-- | noncore/multimedia/showimg/ImageFileSelector.h | 61 | ||||
-rw-r--r-- | noncore/multimedia/showimg/settingsdialog.cpp | 88 | ||||
-rw-r--r-- | noncore/multimedia/showimg/settingsdialog.h | 49 | ||||
-rw-r--r-- | noncore/multimedia/showimg/settingsdialogbase.cpp | 106 | ||||
-rw-r--r-- | noncore/multimedia/showimg/settingsdialogbase.h | 45 | ||||
-rw-r--r-- | noncore/multimedia/showimg/showimg.cpp | 279 | ||||
-rw-r--r-- | noncore/multimedia/showimg/showimg.h | 90 | ||||
-rw-r--r-- | noncore/multimedia/showimg/showimg.pro | 8 |
9 files changed, 623 insertions, 149 deletions
diff --git a/noncore/multimedia/showimg/ImageFileSelector.cpp b/noncore/multimedia/showimg/ImageFileSelector.cpp index 347300f..7872c09 100644 --- a/noncore/multimedia/showimg/ImageFileSelector.cpp +++ b/noncore/multimedia/showimg/ImageFileSelector.cpp @@ -8,90 +8,89 @@ #include <stdlib.h> #include <qdir.h> #include <qwidget.h> #include <qheader.h> #include <qimage.h> #include <qpixmap.h> #include <qlabel.h> #include <qfileinfo.h> #include <qpainter.h> #include <qscrollview.h> #include "ImageFileSelector.h" - - - -ThumbWidget::ThumbWidget(QPixmap p,QString text,const DocLnk& f,QWidget *parent,int w) : QWidget( parent ),fl(f) +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 *e) +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* event) +void ThumbWidget::mouseReleaseEvent(QMouseEvent* ) { emit clicked(fl); } - -ImageFileSelectorItem::ImageFileSelectorItem( QListView *parent, const DocLnk &f): QListViewItem( parent ), fl( f ) +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 *name ):QWidgetStack(parent) +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()); @@ -152,106 +151,101 @@ void ImageFileSelector::setView(CURRENT_VIEW v) 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 purgeCache) +void ImageFileSelector::reread(bool) { +// qDebug("reread"); 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; +// 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 ) - { + + 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 ) - { + 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 ) - { + 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() { + qDebug("image selected"); 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 ); } diff --git a/noncore/multimedia/showimg/ImageFileSelector.h b/noncore/multimedia/showimg/ImageFileSelector.h index 2c346c4..798ebcc 100644 --- a/noncore/multimedia/showimg/ImageFileSelector.h +++ b/noncore/multimedia/showimg/ImageFileSelector.h @@ -1,91 +1,111 @@ #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() - { - - } + ~ThumbWidget() { } - DocLnk file() const - { + 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 - { + 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() - { + 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 ); @@ -96,40 +116,19 @@ private slots: private: void updateSizes(); CURRENT_VIEW cView; int count; QListView *detailed; QScrollView *thumb; QList<ThumbWidget> tList; QWidget *background; QGridLayout *gl; }; - - -class ImageFileSelectorItem : public QListViewItem -{ -public: - ImageFileSelectorItem( QListView *parent, const DocLnk& f ); - ~ImageFileSelectorItem(); - - DocLnk file() const - { - return fl; - } - - -private: - DocLnk fl; -}; - - - - #endif // IMAGEFILE_SELECTOR_H diff --git a/noncore/multimedia/showimg/settingsdialog.cpp b/noncore/multimedia/showimg/settingsdialog.cpp new file mode 100644 index 0000000..55d555a --- a/dev/null +++ b/noncore/multimedia/showimg/settingsdialog.cpp @@ -0,0 +1,88 @@ +/********************************************************************** +** 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> +#include <qradiobutton.h> +#include <qbuttongroup.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/multimedia/showimg/settingsdialog.h b/noncore/multimedia/showimg/settingsdialog.h new file mode 100644 index 0000000..0f47990 --- a/dev/null +++ b/noncore/multimedia/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/multimedia/showimg/settingsdialogbase.cpp b/noncore/multimedia/showimg/settingsdialogbase.cpp new file mode 100644 index 0000000..e0c5bb0 --- a/dev/null +++ b/noncore/multimedia/showimg/settingsdialogbase.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** 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 <qpushbutton.h> +#include <qslider.h> +#include <qlayout.h> +#include <qvariant.h> +#include <qtooltip.h> +#include <qwhatsthis.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/multimedia/showimg/settingsdialogbase.h b/noncore/multimedia/showimg/settingsdialogbase.h new file mode 100644 index 0000000..9594ec6 --- a/dev/null +++ b/noncore/multimedia/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/multimedia/showimg/showimg.cpp b/noncore/multimedia/showimg/showimg.cpp index d7d53ec..0fbffe7 100644 --- a/noncore/multimedia/showimg/showimg.cpp +++ b/noncore/multimedia/showimg/showimg.cpp @@ -11,63 +11,68 @@ ** 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" + +#include <opie/ofiledialog.h> + +#include <qpe/qpeapplication.h> #include <qpe/config.h> #include <qpe/resource.h> #include <qpe/fileselector.h> #include <qpe/applnk.h> #include <qfileinfo.h> #include <math.h> #include <qpe/qpemenubar.h> #include <qwidgetstack.h> #include <qpe/qpetoolbar.h> #include <qaction.h> #include <qfiledialog.h> #include <qmessagebox.h> #include <qpopupmenu.h> #include <qscrollview.h> #include <qlabel.h> #include <qpainter.h> #include <qkeycode.h> #include <qapplication.h> #include <qclipboard.h> #include <qtimer.h> #include <qspinbox.h> -ControlsDialog::ControlsDialog(const QString &caption,QImage image,int *brightness,QWidget *parent):QDialog(parent,0,true) +ControlsDialog::ControlsDialog(const QString &caption,QImage image,int *brightness,QWidget *parent) + : QDialog(parent,0,true) { setCaption(caption); - if ( parent ) - { + 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); @@ -88,35 +93,36 @@ void ControlsDialog::bValueChanged(int value) 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) +InfoDialog::InfoDialog(const QString &caption, const QStringList text,QWidget *parent) + : QDialog(parent,0,true) { setCaption(caption); if ( parent ) { setPalette(parent->palette()); } const char *labels[]={"File Name","Format","File Size","Size","Colors","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; @@ -136,32 +142,34 @@ InfoDialog::InfoDialog(const QString &caption, const QStringList text,QWidget *p 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 ) @@ -216,52 +224,59 @@ ImageViewer::ImageViewer( QWidget *parent, const char *name, int wFlags ) isFullScreen = FALSE; setToolBarsMovable( FALSE ); toolBar = new QPEToolBar( this ); toolBar->setHorizontalStretchable( TRUE ); menuBar = new QPEMenuBar( toolBar ); current=menuBar; fileMenuFile = new QPopupMenu(this); //menuBarmenubarFile->insertItem( tr("File"), fileMenu ); - fileMenuFile->insertItem(tr("Open"), this, SLOT(openFile()), 0); + 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->insertItem( tr("Thumbnail View"), + this, SLOT(switchThumbView()), 0, SHOW_THUMBNAILS ); viewMenuFile->setItemChecked ( SHOW_THUMBNAILS, showThumbView ); optionsMenuFile = new QPopupMenu( this); //menubarFile->insertItem( tr("Options"),optionsMenu ); - optionsMenuFile->insertItem( tr("Slideshow") ); - optionsMenuFile->insertSeparator(); - optionsMenuFile->insertItem( tr("Preferences..")); - optionsMenuFile->insertItem( tr("Help")); - + 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); @@ -278,33 +293,37 @@ ImageViewer::ImageViewer( QWidget *parent, const char *name, int wFlags ) if(showThumbView) cv=ImageFileSelector::THUMBNAIL; else cv=ImageFileSelector::DETAILED; qDebug("cv = %d",cv); 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 & ) ) ); + connect( fileSelector, SIGNAL( fileSelected( const DocLnk &) ), + this, SLOT( openFile( const DocLnk & ) ) ); + + imageList = fileSelector->fileList(); + slideAction->setEnabled( imageList.count() != 0); iconToolBar = new QPEToolBar(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 ); @@ -323,92 +342,153 @@ ImageViewer::ImageViewer( QWidget *parent, const char *name, int wFlags ) 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 ); + 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 ) { + qDebug("<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>"); + 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 ) - { + if ( isSized ) { imagePanel->setPixmap(pmScaled); - } - else - { + } 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); } @@ -421,98 +501,125 @@ void ImageViewer::setDocument(const QString& fileref) QTimer::singleShot( 0, this, SLOT(doDelayedLoad()) ); } void ImageViewer::doDelayedLoad() { show(delayLoad); } void ImageViewer::show() { normalView(); QMainWindow::show(); } void ImageViewer::show(const QString& fileref) { +// qDebug("Show "+fileref); bFromDocView = TRUE; closeFileSelector(); DocLnk link(fileref); - if ( link.isValid() ) - { + if ( link.isValid() ) { openFile(link); - } - else - { + } else { filename = fileref; updateCaption( fileref ); loadImage( fileref ); } } -void ImageViewer::openFile( const DocLnk &file ) +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); +// DocLnk link(file); + qDebug("open "+link.name()); 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 ) - { + 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 ) - { + if ( ok ) { ok = reconvertImage(); updateImageInfo(filename); } - if ( !ok ) - { + 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() ); @@ -606,87 +713,89 @@ 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 ) - { + 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); @@ -694,32 +803,37 @@ void ImageViewer::displayInfoDialog() 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(); } } @@ -1021,24 +1135,115 @@ QImage ImageViewer::rotate(QImage &img, RotateDirection r) { 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/multimedia/showimg/showimg.h b/noncore/multimedia/showimg/showimg.h index 0d3bc7d..8555ff0 100644 --- a/noncore/multimedia/showimg/showimg.h +++ b/noncore/multimedia/showimg/showimg.h @@ -16,63 +16,61 @@ ** 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 QPEToolBar; class QPEMenuBar; 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 ) - { + ImageWidget( QWidget *parent=0 ) + : QWidget( parent ) { setBackgroundMode(NoBackground); } - ~ImageWidget() - { + ~ImageWidget() { } - } - - void setPixmap( const QPixmap &pm ) - { + 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 @@ -103,196 +101,188 @@ private slots: void accept(); private: ImageWidget *pixmap; QSpinBox *spb; QImage img; int *b; }; class ImagePane : public QWidget { Q_OBJECT public: ImagePane( QWidget *parent=0 ); - ~ImagePane() - { - - } + ~ImagePane() { } //void showStatus(); //void hideStatus(); //QLabel *statusLabel() //{ // return status; //} void setPixmap( const QPixmap &pm ); - int paneWidth() const - { + int paneWidth() const { return image->visibleWidth(); } - int paneHeight() const - { + int paneHeight() const { return image->visibleHeight(); } - void setPosition(int x, int y) - { + void setPosition(int x, int y) { image->setContentsPos (x,y ); } - void disable() - { + 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: 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 - { + enum INFO_STRINGS { PATH, FORMAT, FILE_SIZE, SIZE, COLORS, ALPHA, LAST }; - enum RotateDirection - { + 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 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: - - - - - enum MENU_ITEMS - { + 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 QPEToolBar *toolBar; QPEToolBar *iconToolBar; QPEMenuBar *menuBar; QPEMenuBar *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... - bool showThumbView; // a flag to indicate if FileSelector should be initialized with thumbnail 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/multimedia/showimg/showimg.pro b/noncore/multimedia/showimg/showimg.pro index 2b6241f..4ff4746 100644 --- a/noncore/multimedia/showimg/showimg.pro +++ b/noncore/multimedia/showimg/showimg.pro @@ -1,27 +1,25 @@ TEMPLATE = app CONFIG += qt warn_on release DESTDIR = $(OPIEDIR)/bin -HEADERS = showimg.h ImageFileSelector.h -SOURCES = main.cpp \ - showimg.cpp\ - ImageFileSelector.cpp +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 +LIBS += -lqpe -lopie REQUIRES = showimg TRANSLATIONS = ../../../i18n/de/showimg.ts \ ../../../i18n/en/showimg.ts \ ../../../i18n/es/showimg.ts \ ../../../i18n/fr/showimg.ts \ ../../../i18n/hu/showimg.ts \ ../../../i18n/ja/showimg.ts \ ../../../i18n/ko/showimg.ts \ ../../../i18n/no/showimg.ts \ ../../../i18n/pl/showimg.ts \ ../../../i18n/pt/showimg.ts \ ../../../i18n/pt_BR/showimg.ts \ ../../../i18n/sl/showimg.ts \ ../../../i18n/zh_CN/showimg.ts \ ../../../i18n/zh_TW/showimg.ts |