-rw-r--r-- | noncore/graphics/opie-eye/gui/iconview.cpp | 8 | ||||
-rw-r--r-- | noncore/graphics/opie-eye/gui/iconview.h | 1 | ||||
-rw-r--r-- | noncore/graphics/opie-eye/gui/mainwindow.cpp | 2 | ||||
-rw-r--r-- | noncore/graphics/opie-eye/impl/dir/dir_dirview.cpp | 12 | ||||
-rw-r--r-- | noncore/graphics/opie-eye/impl/dir/dir_dirview.h | 2 | ||||
-rw-r--r-- | noncore/graphics/opie-eye/impl/dir/dir_ifaceinfo.cpp | 30 | ||||
-rw-r--r-- | noncore/graphics/opie-eye/impl/dir/dir_lister.cpp | 55 | ||||
-rw-r--r-- | noncore/graphics/opie-eye/impl/dir/dir_lister.h | 12 |
8 files changed, 94 insertions, 28 deletions
diff --git a/noncore/graphics/opie-eye/gui/iconview.cpp b/noncore/graphics/opie-eye/gui/iconview.cpp index 7c8c88d..eafff1d 100644 --- a/noncore/graphics/opie-eye/gui/iconview.cpp +++ b/noncore/graphics/opie-eye/gui/iconview.cpp @@ -108,96 +108,97 @@ namespace { calcRect(text()); } inline QPixmap* IconViewItem::pixmap()const { // owarn << "Name is " << m_path.right( 15 ) << " rect is " << rect().x() << " " << rect().y() // << " " << rect().width() << " " << rect().height() << " | " << iconView()->contentsX() // << " " << iconView()->contentsY() << oendl; if (textOnly()&&!m_isDir) { if (!_emptyPix) _emptyPix = new QPixmap(0,0,1); return _emptyPix; } if ( m_isDir ) return _dirPix; else{ if (!m_noInfo && !g_stringInf.contains( m_path ) ) { currentView()->dirLister()->imageInfo( m_path ); g_stringInf.insert( m_path, const_cast<IconViewItem*>(this)); } m_pix = PPixmapCache::self()->cachedImage( m_path, 64, 64 ); if (!m_pix && !g_stringPix.contains( m_path )) { currentView()->dirLister()->thumbNail( m_path, 64, 64 ); g_stringPix.insert( m_path, const_cast<IconViewItem*>(this)); } return m_pix ? m_pix : _unkPix; } } inline void IconViewItem::setText( const QString& str ) { QString text = QIconViewItem::text()+"\n"+str; m_noInfo = true; QIconViewItem::setText( text ); } } /* * Set up the GUI.. initialize the slave set up gui * and also load a dir */ PIconView::PIconView( QWidget* wid, Opie::Core::OConfig* cfg ) : QVBox( wid ), m_cfg( cfg ), m_updatet( false ) { { QCopEnvelope( "QPE/Application/opie-eye_slave", "refUp()" ); } m_path = QDir::homeDirPath(); m_mode = 0; + m_internalReset = false; QHBox *hbox = new QHBox( this ); QLabel* lbl = new QLabel( hbox ); lbl->setText( tr("View as" ) ); m_views = new QComboBox( hbox, "View As" ); m_view= new QIconView( this ); connect(m_view, SIGNAL(clicked(QIconViewItem*) ), this, SLOT(slotClicked(QIconViewItem*)) ); connect(m_view, SIGNAL(returnPressed(QIconViewItem*)), this, SLOT(slotClicked(QIconViewItem*)) ); m_view->setArrangement( QIconView::LeftToRight ); m_mode = m_cfg->readNumEntry("ListViewMode", 1); QString lastView = m_cfg->readEntry("LastView",""); if (m_mode < 1 || m_mode>3) m_mode = 1; m_view->setItemTextPos( QIconView::Right ); calculateGrid(); initKeys(); loadViews(); int cc=0; for (; cc<m_views->count();++cc) { if (m_views->text(cc)==lastView) { break; } } if (cc<m_views->count()) { m_views->setCurrentItem(cc); slotViewChanged(cc); } else { slotViewChanged(m_views->currentItem()); } connect( m_views, SIGNAL(activated(int)), this, SLOT(slotViewChanged(int)) ); } /* * Unref the slave and save the keyboard manager */ PIconView::~PIconView() { { @@ -318,141 +319,146 @@ QString PIconView::nextFileName(bool &isDir)const QIconViewItem* _it = _it1->nextItem(); if ( !_it ) return QString::null; IconViewItem* it = static_cast<IconViewItem*>( _it ); isDir = it->isDir(); return it->path(); } QString PIconView::prevFileName(bool &isDir)const{ isDir = false; QIconViewItem* _it = m_view->currentItem(); if ( !_it ) return QString::null; _it = _it->prevItem(); if ( !_it ) return QString::null; IconViewItem* it = static_cast<IconViewItem*>( _it ); isDir = it->isDir(); return it->path(); } void PIconView::slotTrash() { bool isDir; QString pa = currentFileName( isDir ); if ( isDir && pa.isEmpty() ) return; if (!QPEMessageBox::confirmDelete( this, tr("Delete Image" ), tr("the Image %1" ).arg(pa))) return currentView()->dirLister()->deleteImage( pa ); delete m_view->currentItem(); } /* * see what views are available */ void PIconView::loadViews() { ViewMap::Iterator it; ViewMap* map = viewMap(); for ( it = map->begin(); it != map->end(); ++it ) m_views->insertItem( it.key() ); } void PIconView::resetView() { + m_internalReset = true; slotViewChanged(m_views->currentItem()); + m_internalReset = false; } /* *swicth view reloadDir and connect signals */ void PIconView::slotViewChanged( int i) { if (!m_views->count() ) { setCurrentView( 0l); return; } PDirView* cur = currentView(); if (cur) delete cur; QString str = m_views->text(i); ViewMap* map = viewMap(); if (!map) { setCurrentView(0l); return; } if (map->find(str) == map->end()) { owarn << "Key not found" << oendl; setCurrentView(0l); return; } m_cfg->writeEntry("LastView",str); m_cfg->write(); cur = (*(*map)[str])(*m_cfg); setCurrentView( cur ); /* connect to the signals of the lister */ PDirLister* lis = cur->dirLister(); connect(lis, SIGNAL(sig_thumbInfo(const QString&, const QString& )), this, SLOT( slotThumbInfo(const QString&, const QString&))); connect(lis, SIGNAL( sig_thumbNail(const QString&, const QPixmap&)), this, SLOT(slotThumbNail(const QString&, const QPixmap&))); connect(lis, SIGNAL(sig_start()), this, SLOT(slotStart())); connect(lis, SIGNAL(sig_end()) , this, SLOT(slotEnd()) ); - /* reload now with default Path*/ + /* reload now with default Path + * but only if it isn't a reset like from setupdlg + */ + if (!m_internalReset) m_path = lis->defaultPath(); QTimer::singleShot( 0, this, SLOT(slotReloadDir())); } void PIconView::slotReloadDir() { slotChangeDir( m_path ); } /* * add files and folders */ void PIconView::addFolders( const QStringList& lst) { QStringList::ConstIterator it; IconViewItem * _iv; for(it=lst.begin(); it != lst.end(); ++it ) { _iv = new IconViewItem( m_view, m_path+"/"+(*it), (*it), true ); if (m_mode==3) _iv->setTextOnly(true); } } void PIconView::addFiles( const QStringList& lst) { QStringList::ConstIterator it; IconViewItem * _iv; QPixmap*m_pix = 0; QString pre = ""; if (!m_path.isEmpty()) { pre = m_path+"/"; } for (it=lst.begin(); it!= lst.end(); ++it ) { m_pix = PPixmapCache::self()->cachedImage( pre+(*it), 64, 64 ); _iv = new IconViewItem( m_view, pre+(*it), (*it) ); if (m_mode==3) { _iv->setTextOnly(true); _iv->setPixmap(QPixmap()); } else { if (m_pix) _iv->setPixmap(*m_pix); } } } /* diff --git a/noncore/graphics/opie-eye/gui/iconview.h b/noncore/graphics/opie-eye/gui/iconview.h index dff55ed..bea35c2 100644 --- a/noncore/graphics/opie-eye/gui/iconview.h +++ b/noncore/graphics/opie-eye/gui/iconview.h @@ -50,51 +50,52 @@ protected: void resizeEvent( QResizeEvent* ); private: void initKeys(); QString currentFileName(bool &isDir)const; QString nextFileName(bool &isDir)const; QString prevFileName(bool &isDir)const; void loadViews(); void calculateGrid(); private slots: void slotDirUp(); void slotChangeDir(const QString&); void slotTrash(); void slotViewChanged( int ); void slotReloadDir(); void slotRename(); void slotBeam(); void slotBeamDone( Ir* ); void slotShowImage(); void slotShowImage( const QString& ); void slotImageInfo(); void slotImageInfo( const QString& ); void slotStartSlide(); void slotStart(); void slotEnd(); /* for performance reasons make it inline in the future */ void addFolders( const QStringList& ); void addFiles( const QStringList& ); void slotClicked(QIconViewItem* ); void slotRetrun(QIconViewItem* ); /**/ void slotThumbInfo(const QString&, const QString&); void slotThumbNail(const QString&, const QPixmap&); void slotChangeMode( int ); private: Opie::Core::OKeyConfigManager *m_viewManager; Opie::Core::OConfig *m_cfg; QComboBox* m_views; QIconView* m_view; QString m_path; bool m_updatet : 1; int m_mode; + bool m_internalReset:1; }; #endif diff --git a/noncore/graphics/opie-eye/gui/mainwindow.cpp b/noncore/graphics/opie-eye/gui/mainwindow.cpp index 6660eb2..30c9bf1 100644 --- a/noncore/graphics/opie-eye/gui/mainwindow.cpp +++ b/noncore/graphics/opie-eye/gui/mainwindow.cpp @@ -128,103 +128,105 @@ void PMainWindow::slotScaleToggled(bool how) m_disp->setAutoScaleRotate(!m_aUnscaled->isOn(),m_aAutoRotate->isOn()); } m_aAutoRotate->setEnabled(!how); odebug << "Autorotate: " << m_aAutoRotate->isOn() << oendl; } void PMainWindow::slotConfig() { /* * have a tab with the possible views * a tab for globals image cache size.. scaled loading * and one tab for the KeyConfigs */ QDialog dlg(this, 0, true); dlg.setCaption( tr("Opie Eye - Config" ) ); QHBoxLayout *lay = new QHBoxLayout(&dlg); Opie::Ui::OTabWidget *wid = new Opie::Ui::OTabWidget(&dlg ); lay->addWidget( wid ); BaseSetup*bSetup = new BaseSetup(m_cfg,wid); wid->addTab(bSetup,"SettingsIcon","Basics setup"); ViewMap *vM = viewMap(); ViewMap::Iterator _it = vM->begin(); QMap<PDirView*, QWidget*> lst; for( ; _it != vM->end(); ++_it ) { PDirView *view = (_it.data())(*m_cfg); PInterfaceInfo *inf = view->interfaceInfo(); QWidget *_wid = inf->configWidget( *m_cfg ); if (!_wid) continue; _wid->reparent(wid, QPoint() ); lst.insert( view, _wid ); wid->addTab( _wid, "fileopen", inf->name() ); } /* * Add the KeyConfigWidget */ Opie::Ui::OKeyConfigWidget* keyWid = new Opie::Ui::OKeyConfigWidget( wid, "key config" ); keyWid->setChangeMode( Opie::Ui::OKeyConfigWidget::Queue ); keyWid->insert( tr("Browser Keyboard Actions"), m_view->manager() ); QWidget*w = m_stack->visibleWidget(); bool reminfo = false; if ( !m_info ) { reminfo = true; initInfo(); + m_info->hide(); } keyWid->insert( tr("Imageinfo Keyboard Actions"), m_info->manager() ); bool remdisp = false; if ( !m_disp ) { remdisp = true; initDisp(); + m_disp->hide(); } keyWid->insert( tr("Imageview Keyboard Actions"), m_disp->manager() ); keyWid->load(); wid->addTab( keyWid, QString::fromLatin1("AppsIcon" ), tr("Keyboard Configuration") ); wid->setCurrentTab(0); bool act = ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted ); /* * clean up *apply changes */ QMap<PDirView*, QWidget*>::Iterator it; for ( it = lst.begin(); it != lst.end(); ++it ) { if ( act ) it.key()->interfaceInfo()->writeConfig(it.data(), *m_cfg); delete it.key(); } if ( act ) { m_view->resetView(); keyWid->save(); m_disp->manager()->save(); m_info->manager()->save(); m_view->manager()->save(); bSetup->save_values(); readConfig(); } delete keyWid; m_stack->raiseWidget(w); if (remdisp) { m_disp->hide(); } if (reminfo) { m_info->hide(); } } /* * create a new image info component * and detach the current one * we will make the other delete on exit */ template<class T> void PMainWindow::initT( const char* name, T** ptr, int id) { diff --git a/noncore/graphics/opie-eye/impl/dir/dir_dirview.cpp b/noncore/graphics/opie-eye/impl/dir/dir_dirview.cpp index 97e3dcb..fc502d4 100644 --- a/noncore/graphics/opie-eye/impl/dir/dir_dirview.cpp +++ b/noncore/graphics/opie-eye/impl/dir/dir_dirview.cpp @@ -1,29 +1,33 @@ #include "dir_lister.h" #include "dir_ifaceinfo.h" #include "dir_dirview.h" PHUNK_VIEW_INTERFACE("Dir View", Dir_DirView ); Dir_DirView::Dir_DirView( const Config& cfg) : PDirView(cfg) { - m_cfg = cfg.readBoolEntry( "Dir_Check_All_Files", true); + m_cfg = cfg.readBoolEntry( "Dir_Check_All_Files", false); + m_recursive = cfg.readBoolEntry( "Dir_Check_Recursive_Files", false); + m_recursive_depth = cfg.readNumEntry("Dir_Recursive_Files_Depth",10); m_lister = 0; m_info = 0; } Dir_DirView::~Dir_DirView() { } PInterfaceInfo* Dir_DirView::interfaceInfo()const{ - if (!m_info ) + if (!m_info ) { m_info =new DirInterfaceInfo; + } return m_info; } PDirLister* Dir_DirView::dirLister()const{ - if (!m_lister ) - m_lister = new Dir_DirLister(m_cfg); + if (!m_lister ) { + m_lister = new Dir_DirLister(m_cfg,m_recursive,m_recursive_depth); + } return m_lister; } diff --git a/noncore/graphics/opie-eye/impl/dir/dir_dirview.h b/noncore/graphics/opie-eye/impl/dir/dir_dirview.h index 3b9b7a6..89cf6c9 100644 --- a/noncore/graphics/opie-eye/impl/dir/dir_dirview.h +++ b/noncore/graphics/opie-eye/impl/dir/dir_dirview.h @@ -1,24 +1,26 @@ /* * GPLv2 only zecke@handhelds.org */ #ifndef DIR_DIR_VIEW_H #define DIR_DIR_VIEW_H #include <iface/dirview.h> struct Dir_DirView : public PDirView { Dir_DirView( const Config& ); ~Dir_DirView(); PInterfaceInfo* interfaceInfo()const; PDirLister* dirLister()const; private: bool m_cfg : 1; + bool m_recursive:1; + int m_recursive_depth; mutable PDirLister* m_lister; mutable PInterfaceInfo *m_info; }; #endif diff --git a/noncore/graphics/opie-eye/impl/dir/dir_ifaceinfo.cpp b/noncore/graphics/opie-eye/impl/dir/dir_ifaceinfo.cpp index 9c69ce5..1e4ec40 100644 --- a/noncore/graphics/opie-eye/impl/dir/dir_ifaceinfo.cpp +++ b/noncore/graphics/opie-eye/impl/dir/dir_ifaceinfo.cpp @@ -1,58 +1,82 @@ /* * GPLv2 * zecke@handhelds.org */ #include "dir_ifaceinfo.h" /* OPIE */ #include <opie2/odebug.h> #include <qpe/config.h> /* QT */ #include <qwidget.h> #include <qcheckbox.h> #include <qframe.h> #include <qhbox.h> #include <qlabel.h> #include <qlayout.h> +#include <qspinbox.h> namespace { class DirImageWidget : public QFrame { public: DirImageWidget(): QFrame() { setFrameStyle(Box|Raised); QVBoxLayout *m_MainLayout = new QVBoxLayout( this, 6, 2, "m_MainLayout"); + QGridLayout*RecDepthLayout = new QGridLayout( 0, 1, 1, 0, 6, "RecDepthLayout"); + chkbox = new QCheckBox( QObject::tr("Show all files"), this ); m_MainLayout->addWidget(chkbox); + recWarningLabel = new QLabel(this); + recWarningLabel->setText(QObject::tr("<center><b>Be carefull with the following options!</b></center>")); + m_MainLayout->addWidget(recWarningLabel); + recBox = new QCheckBox( QObject::tr("Show files recursive"),this); + m_MainLayout->addWidget(recBox); + recDepthLabel = new QLabel(this); + recDepthLabel->setText(QObject::tr("Recursion depth:")); + RecDepthLayout->addWidget(recDepthLabel,0,0); + recDepth = new QSpinBox(this); + recDepth->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::Fixed)); + recDepth->setMaxValue(10); + recDepth->setMinValue(1); + recDepth->setSuffix(QObject::tr(" directories")); + RecDepthLayout->addWidget(recDepth,0,1); + m_MainLayout->addLayout(RecDepthLayout); QSpacerItem *spacer1 = new QSpacerItem( 20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding ); m_MainLayout->addItem( spacer1 ); } ~DirImageWidget() {} - QCheckBox* chkbox; + QCheckBox* chkbox,*recBox; + QSpinBox * recDepth; + QLabel* recDepthLabel,*recWarningLabel; + }; } DirInterfaceInfo::DirInterfaceInfo() { } DirInterfaceInfo::~DirInterfaceInfo() { } QString DirInterfaceInfo::name()const { return QObject::tr("Directory View" ); } QWidget* DirInterfaceInfo::configWidget(const Config& cfg) { DirImageWidget* wid = new DirImageWidget(); - wid->chkbox->setChecked( cfg.readBoolEntry("Dir_Check_All_Files", true) ); - + wid->chkbox->setChecked(cfg.readBoolEntry("Dir_Check_All_Files",false)); + wid->recBox->setChecked(cfg.readBoolEntry("Dir_Check_Recursive_Files",false)); + wid->recDepth->setValue(cfg.readNumEntry("Dir_Recursive_Files_Depth",10)); return wid; } void DirInterfaceInfo::writeConfig( QWidget* _wid, Config& cfg) { owarn << "Write Config" << oendl; DirImageWidget* wid = static_cast<DirImageWidget*>(_wid); cfg.writeEntry("Dir_Check_All_Files", wid->chkbox->isChecked() ); + cfg.writeEntry("Dir_Check_Recursive_Files", wid->recBox->isChecked()); + cfg.writeEntry("Dir_Recursive_Files_Depth",wid->recDepth->value()); } diff --git a/noncore/graphics/opie-eye/impl/dir/dir_lister.cpp b/noncore/graphics/opie-eye/impl/dir/dir_lister.cpp index d8b332a..ff33cf2 100644 --- a/noncore/graphics/opie-eye/impl/dir/dir_lister.cpp +++ b/noncore/graphics/opie-eye/impl/dir/dir_lister.cpp @@ -1,92 +1,111 @@ /* * GPLv2 zecke@handhelds.org */ #include "dir_lister.h" #include <lib/slavemaster.h> /* OPIE */ #include <opie2/odebug.h> #include <qpe/config.h> #include <qpe/qpeapplication.h> using namespace Opie::Core; /* QT */ #include <qdir.h> #include <qfileinfo.h> -Dir_DirLister::Dir_DirLister( bool list ) +Dir_DirLister::Dir_DirLister( bool list,bool rec,int recdepth ) : PDirLister( "dir_dir_lister" ) { m_allFiles = list; + m_recursive = rec; + m_recDepth = recdepth; + if (m_recDepth<1) m_recDepth = 1; + if (m_recDepth>10) m_recDepth = 10; owarn << "All Files " << m_allFiles << "" << oendl; SlaveHelper::slaveConnectSignals( this ); + m_Filter = (m_allFiles?"*":"*.jpg;*.jpeg;*.JPG;*.PNG;*.GIF;*.BMP;*.png;*.bmp;*.gif"); } QString Dir_DirLister::defaultPath()const { return QPEApplication::documentDir(); } QString Dir_DirLister::setStartPath( const QString& path ) { m_currentDir.cd( path ); if (!m_currentDir.exists() ) m_currentDir.cd(defaultPath()); return m_currentDir.absPath(); } QString Dir_DirLister::currentPath()const { return m_currentDir.absPath(); } QStringList Dir_DirLister::folders()const { return m_currentDir.entryList( QDir::Dirs ); } -QStringList Dir_DirLister::files()const { - if ( m_allFiles ) - return m_currentDir.entryList( QDir::Files ); - else { - QStringList out; - QStringList list = m_currentDir.entryList( QDir::Files | QDir::Readable ); - for (QStringList::Iterator it = list.begin(); it != list.end();++it ) { - QFileInfo inf( *it ); - QString ext = inf.extension(false).lower(); - if( ext == QString::fromLatin1("jpg") || - ext == QString::fromLatin1("jpeg" ) || - ext == QString::fromLatin1("png" ) || - ext == QString::fromLatin1("bmp" ) || - ext == QString::fromLatin1("gif" ) ) - out.append( *it ); - } - return out; +QStringList Dir_DirLister::recFiles(const QString&aPath,int currentDepth)const +{ + QStringList all; + if (currentDepth>m_recDepth) return all; + + QString subPath; + subPath = aPath; + if (subPath.length()==0) { + subPath="."; + } + QDir checkDir(currentPath()+"/"+aPath); + + QStringList p = checkDir.entryList( QDir::Dirs ); + all+=checkDir.entryList(m_Filter,QDir::Files|QDir::Readable); + QStringList tmp; + for (unsigned i = 0; i < p.count();++i) { + if (p[i]=="." || p[i]=="..") continue; + tmp =recFiles(subPath+"/"+p[i],currentDepth+1); + for (unsigned j = 0; j < tmp.count();++j) { + all.append(p[i]+"/"+tmp[j]); + } + } + return all; +} + +QStringList Dir_DirLister::files()const +{ + if (m_recursive) { + odebug << "Startpfad: "<<m_currentDir.absPath()<<oendl; + return recFiles("",0); } + return m_currentDir.entryList(m_Filter,QDir::Files|QDir::Readable); } void Dir_DirLister::deleteImage( const QString& fl) { QFile::remove( fl ); } void Dir_DirLister::thumbNail( const QString& str, int w, int h) { SlaveMaster::self()->thumbNail( str, w, h ); } QImage Dir_DirLister::image( const QString& str, Factor f, int m) { return SlaveMaster::self()->image( str, f, m ); } void Dir_DirLister::imageInfo( const QString& str) { SlaveMaster::self()->thumbInfo( str ); } void Dir_DirLister::fullImageInfo( const QString& str) { SlaveMaster::self()->imageInfo( str ); } QString Dir_DirLister::nameToFname(const QString&name)const { return name; } diff --git a/noncore/graphics/opie-eye/impl/dir/dir_lister.h b/noncore/graphics/opie-eye/impl/dir/dir_lister.h index d6ca6c0..445adbf 100644 --- a/noncore/graphics/opie-eye/impl/dir/dir_lister.h +++ b/noncore/graphics/opie-eye/impl/dir/dir_lister.h @@ -1,37 +1,45 @@ /* * GPLv2 zecke@handhelds.org */ #ifndef DIR_LISTER_INTERFACE_LISTER_H #define DIR_LISTER_INTERFACE_LISTER_H #include <qdir.h> #include <iface/dirlister.h> class Config; class Dir_DirLister : public PDirLister { Q_OBJECT public: - Dir_DirLister( bool ); + Dir_DirLister(bool,bool,int); virtual ~Dir_DirLister(){} QString defaultPath()const; QString setStartPath( const QString& ); QString currentPath()const; QStringList folders()const; QStringList files()const; void deleteImage( const QString& ); void thumbNail( const QString&, int, int ); QImage image( const QString&, Factor, int ); void imageInfo( const QString& ); void fullImageInfo( const QString& ); virtual QString nameToFname(const QString&name)const; private: - bool m_allFiles; + bool m_allFiles:1; + bool m_recursive:1; + int m_recDepth; QDir m_currentDir; + //! recursive listing. + /*! + * \param path this is the offset to the current path. eg. when currentDepth = 0 then it MUST empty + */ + QStringList recFiles(const QString&path,int currentDepth)const; + QString m_Filter; }; #endif |