MythTV  0.26-pre
iconview.cpp
Go to the documentation of this file.
00001 /* ============================================================
00002  * File  : iconview.cpp
00003  * Description :
00004  *
00005  * This program is free software; you can redistribute it
00006  * and/or modify it under the terms of the GNU General
00007  * Public License as published bythe Free Software Foundation;
00008  * either version 2, or (at your option)
00009  * any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * ============================================================ */
00017 
00018 // POSIX headers
00019 #include <unistd.h>
00020 
00021 // ANSI C headers
00022 #include <cmath>
00023 
00024 // C++ headers
00025 #include <algorithm>
00026 
00027 using namespace std;
00028 
00029 // Qt headers
00030 #include <QApplication>
00031 #include <QEvent>
00032 #include <QDir>
00033 #include <QMatrix>
00034 #include <QList>
00035 #include <QFileInfo>
00036 
00037 // MythTV headers
00038 #include <mythmiscutil.h>
00039 #include <mythdbcon.h>
00040 #include <httpcomms.h>
00041 #include <mythcontext.h>
00042 #include <mythlogging.h>
00043 #include <mythmainwindow.h>
00044 #include <mythprogressdialog.h>
00045 #include <mythmediamonitor.h>
00046 
00047 // MythGallery headers
00048 #include "galleryutil.h"
00049 #include "gallerysettings.h"
00050 #include "galleryfilter.h"
00051 #include "thumbgenerator.h"
00052 #include "iconview.h"
00053 #include "singleview.h"
00054 #include "glsingleview.h"
00055 
00056 #define LOC QString("IconView: ")
00057 
00058 QEvent::Type ChildCountEvent::kEventType =
00059     (QEvent::Type) QEvent::registerEventType();
00060 
00061 class FileCopyThread : public MThread
00062 {
00063   public:
00064     FileCopyThread(IconView *parent, bool move);
00065     virtual void run();
00066     int GetProgress(void) { return m_progress; }
00067 
00068   private:
00069     bool         m_move;
00070     IconView    *m_parent;
00071     volatile int m_progress;
00072 };
00073 
00074 FileCopyThread::FileCopyThread(IconView *parent, bool move) :
00075     MThread("FileCopy"), m_move(move), m_parent(parent), m_progress(0)
00076 {
00077 }
00078 
00079 void FileCopyThread::run()
00080 {
00081     RunProlog();
00082 
00083     QStringList::iterator it;
00084     QFileInfo fi;
00085     QFileInfo dest;
00086 
00087     m_progress = 0;
00088 
00089     for (it = m_parent->m_itemMarked.begin();
00090          it != m_parent->m_itemMarked.end(); ++it)
00091     {
00092         fi.setFile(*it);
00093         dest.setFile(QDir(m_parent->m_currDir), fi.fileName());
00094 
00095         if (fi.exists())
00096             GalleryUtil::CopyMove(fi, dest, m_move);
00097 
00098         m_progress++;
00099     }
00100 
00101     RunEpilog();
00102 }
00103 
00105 
00106 IconView::IconView(MythScreenStack *parent, const char *name,
00107                    const QString &galleryDir, MythMediaDevice *initialDevice)
00108         : MythScreenType(parent, name)
00109 {
00110     m_galleryDir = galleryDir;
00111     m_galleryFilter = new GalleryFilter();
00112 
00113     m_isGallery = false;
00114     m_showDevices = false;
00115     m_currDevice = initialDevice;
00116 
00117     m_thumbGen = new ThumbGenerator(this, 0, 0);
00118     m_childCountThread = new ChildCountThread(this);
00119 
00120     m_showcaption = gCoreContext->GetNumSetting("GalleryOverlayCaption", 0);
00121     m_sortorder = gCoreContext->GetNumSetting("GallerySortOrder", 0);
00122     m_useOpenGL = gCoreContext->GetNumSetting("SlideshowUseOpenGL", 0);
00123     m_recurse = gCoreContext->GetNumSetting("GalleryRecursiveSlideshow", 0);
00124     m_paths = gCoreContext->GetSetting("GalleryImportDirs").split(":");
00125     m_errorStr = QString::null;
00126 
00127     m_captionText = NULL;
00128     m_noImagesText = NULL;
00129     m_selectedImage = NULL;
00130 
00131     m_menuPopup = NULL;
00132 
00133     QDir dir(m_galleryDir);
00134     if (!dir.exists() || !dir.isReadable())
00135     {
00136         m_errorStr = tr("MythGallery Directory '%1' does not exist "
00137                         "or is unreadable.").arg(m_galleryDir);
00138         return;
00139     }
00140 
00141     m_popupStack = GetMythMainWindow()->GetStack("popup stack");
00142 }
00143 
00144 IconView::~IconView()
00145 {
00146     if (m_thumbGen)
00147     {
00148         delete m_thumbGen;
00149         m_thumbGen = NULL;
00150     }
00151     if (m_galleryFilter)
00152     {
00153         delete m_galleryFilter;
00154         m_galleryFilter = NULL;
00155     }
00156     if (m_childCountThread)
00157     {
00158         delete m_childCountThread;
00159         m_childCountThread = NULL;
00160     }
00161 }
00162 
00163 bool IconView::Create(void)
00164 {
00165     bool foundtheme = false;
00166 
00167     // Load the theme for this screen
00168     foundtheme = LoadWindowFromXML("gallery-ui.xml", "gallery", this);
00169 
00170     if (!foundtheme)
00171         return false;
00172 
00173     bool err = false;
00174     UIUtilE::Assign(this, m_imageList,     "images", &err);
00175     UIUtilW::Assign(this, m_captionText,   "title");
00176     UIUtilW::Assign(this, m_noImagesText,  "noimages");
00177     UIUtilW::Assign(this, m_selectedImage, "selectedimage");
00178     UIUtilW::Assign(this, m_positionText,  "position");
00179     UIUtilW::Assign(this, m_crumbsText,    "breadcrumbs");
00180 
00181     if (err)
00182     {
00183         LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'gallery'");
00184         return false;
00185     }
00186 
00187     connect(m_imageList, SIGNAL(itemClicked( MythUIButtonListItem*)),
00188             this, SLOT( HandleItemSelect(MythUIButtonListItem*)));
00189     connect(m_imageList, SIGNAL(itemSelected( MythUIButtonListItem*)),
00190             this, SLOT( UpdateText(MythUIButtonListItem*)));
00191     connect(m_imageList, SIGNAL(itemSelected( MythUIButtonListItem*)),
00192             this, SLOT( UpdateImage(MythUIButtonListItem*)));
00193 
00194     if (m_noImagesText)
00195     {
00196         m_noImagesText->SetText(tr("No images found in this folder."));
00197         m_noImagesText->SetVisible(false);
00198     }
00199 
00200     BuildFocusList();
00201 
00202     // TODO Not accurate, the image may be smaller than the button
00203     int thumbWidth  = m_imageList->ItemWidth();
00204     int thumbHeight = m_imageList->ItemHeight();
00205     if (m_selectedImage && (m_selectedImage->GetArea().width()  > thumbWidth ||
00206                             m_selectedImage->GetArea().height() > thumbHeight))
00207     {
00208        thumbWidth  = m_selectedImage->GetArea().width();
00209        thumbHeight = m_selectedImage->GetArea().height();
00210     }
00211 
00212     if (m_thumbGen)
00213         m_thumbGen->setSize(thumbWidth, thumbHeight);
00214 
00215     SetupMediaMonitor();
00216     if (!m_currDevice)
00217         LoadDirectory(m_galleryDir);
00218 
00219     return true;
00220 }
00221 
00222 void IconView::LoadDirectory(const QString &dir)
00223 {
00224     if (m_thumbGen && m_thumbGen->isRunning())
00225         m_thumbGen->cancel();
00226 
00227     if (m_childCountThread && m_childCountThread->isRunning())
00228         m_childCountThread->cancel();
00229 
00230     QDir d(dir);
00231     if (!d.exists())
00232     {
00233         LOG(VB_GENERAL, LOG_ERR, LOC + "LoadDirectory called with " +
00234                 QString("non-existant directory: '%1'").arg(dir));
00235         return;
00236     }
00237 
00238     m_showDevices = false;
00239 
00240     m_currDir = d.absolutePath();
00241 
00242     while (!m_itemList.isEmpty())
00243         delete m_itemList.takeFirst();
00244 
00245     m_itemHash.clear();
00246     m_imageList->Reset();
00247 
00248     m_isGallery = GalleryUtil::LoadDirectory(m_itemList, dir, *m_galleryFilter,
00249                                              false, &m_itemHash, m_thumbGen);
00250 
00251     if (m_thumbGen && !m_thumbGen->isRunning())
00252         m_thumbGen->start();
00253 
00254     ThumbItem *thumbitem;
00255     for (int x = 0; x < m_itemList.size(); x++)
00256     {
00257         thumbitem = m_itemList.at(x);
00258 
00259         thumbitem->InitCaption(m_showcaption);
00260         MythUIButtonListItem* item =
00261             new MythUIButtonListItem(m_imageList, thumbitem->GetCaption(), 0,
00262                                      true, MythUIButtonListItem::NotChecked);
00263         item->SetData(qVariantFromValue(thumbitem));
00264         if (thumbitem->IsDir())
00265         {
00266             item->DisplayState("subfolder", "nodetype");
00267             m_childCountThread->addFile(thumbitem->GetPath());
00268         }
00269 
00270         LoadThumbnail(thumbitem);
00271 
00272         if (QFile(thumbitem->GetImageFilename()).exists())
00273             item->SetImage(thumbitem->GetImageFilename());
00274 
00275         if (m_itemMarked.contains(thumbitem->GetPath()))
00276             item->setChecked(MythUIButtonListItem::FullChecked);
00277     }
00278 
00279     if (m_childCountThread && !m_childCountThread->isRunning())
00280                 m_childCountThread->start();
00281 
00282     if (m_noImagesText)
00283         m_noImagesText->SetVisible(m_itemList.isEmpty());
00284 
00285     if (!m_itemList.isEmpty())
00286     {
00287         UpdateText(m_imageList->GetItemCurrent());
00288         UpdateImage(m_imageList->GetItemCurrent());
00289     }
00290 }
00291 
00292 void IconView::LoadThumbnail(ThumbItem *item)
00293 {
00294     if (!item)
00295         return;
00296 
00297     bool canLoadGallery = m_isGallery;
00298 
00299     QString imagePath;
00300     if (canLoadGallery)
00301     {
00302         if (item->IsDir())
00303         {
00304             // try to find a highlight
00305             QDir subdir(item->GetPath(), "*.highlight.*",
00306                         QDir::Name, QDir::Files);
00307 
00308             if (subdir.count() > 0)
00309             {
00310                 // check if the image format is understood
00311                 QFileInfoList::const_iterator it = subdir.entryInfoList().begin();
00312                 if (it != subdir.entryInfoList().end())
00313                 {
00314                     imagePath = it->absoluteFilePath();
00315                 }
00316             }
00317         }
00318         else
00319         {
00320             QString fn = item->GetName();
00321             int firstDot = fn.indexOf('.');
00322             if (firstDot > 0)
00323             {
00324                 fn.insert(firstDot, ".thumb");
00325                 imagePath = QString("%1/%2").arg(m_currDir).arg(fn);
00326             }
00327         }
00328 
00329         canLoadGallery = !(QFile(imagePath).exists());
00330     }
00331 
00332     if (!canLoadGallery)
00333         imagePath = QString("%1%2.jpg")
00334                             .arg(ThumbGenerator::getThumbcacheDir(m_currDir))
00335                             .arg(item->GetName());
00336 
00337     item->SetImageFilename(imagePath);
00338 }
00339 
00340 void IconView::SetupMediaMonitor(void)
00341 {
00342 #ifdef _WIN32
00343     if (m_currDevice)
00344         LoadDirectory(m_currDevice->getDevicePath());
00345 #else
00346     MediaMonitor *mon = MediaMonitor::GetMediaMonitor();
00347     if (m_currDevice && mon && mon->ValidateAndLock(m_currDevice))
00348     {
00349         bool mounted = m_currDevice->isMounted();
00350         if (!mounted)
00351             mounted = m_currDevice->mount();
00352 
00353         if (mounted)
00354         {
00355             connect(m_currDevice,
00356                 SIGNAL(statusChanged(MythMediaStatus, MythMediaDevice*)),
00357                 SLOT(mediaStatusChanged(MythMediaStatus, MythMediaDevice*)));
00358 
00359             LoadDirectory(m_currDevice->getMountPath());
00360 
00361             mon->Unlock(m_currDevice);
00362             return;
00363         }
00364         else
00365         {
00366 //             DialogBox *dlg = new DialogBox(GetMythMainWindow(),
00367 //                              tr("Failed to mount device: ") +
00368 //                              m_currDevice->getDevicePath() + "\n\n" +
00369 //                              tr("Showing the default MythGallery directory."));
00370 //             dlg->AddButton(tr("OK"));
00371 //             dlg->exec();
00372 //             dlg->deleteLater();
00373             mon->Unlock(m_currDevice);
00374         }
00375     }
00376 #endif // _WIN32
00377 }
00378 
00379 void IconView::UpdateText(MythUIButtonListItem *item)
00380 {
00381     if (!item)
00382     {
00383         if (m_positionText)
00384             m_positionText->Reset();
00385         return;
00386     }
00387 
00388     if (m_positionText)
00389         m_positionText->SetText(QString(tr("%1 of %2"))
00390                                 .arg(m_imageList->GetCurrentPos() + 1)
00391                                 .arg(m_imageList->GetCount()));
00392 
00393     ThumbItem *thumbitem = qVariantValue<ThumbItem *>(item->GetData());
00394     if (!thumbitem)
00395         return;
00396 
00397     if (m_crumbsText)
00398     {
00399         QString path = thumbitem->GetPath();
00400         path.replace(m_galleryDir, tr("Gallery Home"));
00401         path.replace("/", " > ");
00402         m_crumbsText->SetText(path);
00403     }
00404 
00405     if (m_captionText)
00406     {
00407         QString caption;
00408         caption = thumbitem->GetCaption();
00409         caption = (caption.isNull()) ? "" : caption;
00410         m_captionText->SetText(caption);
00411     }
00412 }
00413 
00414 void IconView::UpdateImage(MythUIButtonListItem *item)
00415 {
00416     if (!m_selectedImage)
00417         return;
00418 
00419     ThumbItem *thumbitem = qVariantValue<ThumbItem *>(item->GetData());
00420 
00421     QString selectedimage;
00422     if (thumbitem)
00423     {
00424         selectedimage = thumbitem->GetImageFilename();
00425         selectedimage = (selectedimage.isNull()) ? "" : selectedimage;
00426     }
00427     m_selectedImage->SetFilename(selectedimage);
00428     m_selectedImage->Load();
00429 }
00430 
00431 
00432 bool IconView::keyPressEvent(QKeyEvent *event)
00433 {
00434     if (GetFocusWidget()->keyPressEvent(event))
00435         return true;
00436 
00437     bool handled = false;
00438     QStringList actions;
00439     handled = GetMythMainWindow()->TranslateKeyPress("Gallery", event, actions);
00440 
00441     for (int i = 0; i < actions.size() && !handled; i++)
00442     {
00443         QString action = actions[i];
00444         handled = true;
00445 
00446         if (!m_itemList.isEmpty())
00447         {
00448             if (action == "MENU")
00449             {
00450                 HandleMainMenu();
00451             }
00452             else if (action == "ROTRIGHT")
00453                 HandleRotateCW();
00454             else if (action == "ROTLEFT")
00455                 HandleRotateCCW();
00456             else if (action == "DELETE")
00457                 HandleDelete();
00458             else if (action == "MARK")
00459             {
00460                 ThumbItem *thumbitem = GetCurrentThumb();
00461                 MythUIButtonListItem *item = m_imageList->GetItemCurrent();
00462 
00463                 if (thumbitem)
00464                 {
00465                     if (!m_itemMarked.contains(thumbitem->GetPath()))
00466                     {
00467                         m_itemMarked.append(thumbitem->GetPath());
00468                         item->setChecked(MythUIButtonListItem::FullChecked);
00469                     }
00470                     else
00471                     {
00472                         m_itemMarked.removeAll(thumbitem->GetPath());
00473                         item->setChecked(MythUIButtonListItem::NotChecked);
00474                     }
00475                 }
00476             }
00477             else if (action == "SLIDESHOW")
00478                 HandleSlideShow();
00479             else if (action == "RANDOMSHOW")
00480                 HandleRandomShow();
00481             else
00482                 handled = false;
00483         }
00484 
00485         if (action == "ESCAPE")
00486         {
00487             if (GetMythMainWindow()->IsExitingToMain())
00488             {
00489                 while ( m_currDir != m_galleryDir &&
00490                         HandleSubDirEscape(m_galleryDir) );
00491             }
00492             handled = HandleEscape();
00493         }
00494     }
00495 
00496     if (!handled && MythScreenType::keyPressEvent(event))
00497         handled = true;
00498 
00499     return handled;
00500 }
00501 
00502 void IconView::HandleItemSelect(MythUIButtonListItem *item)
00503 {
00504     bool handled = false;
00505 
00506     ThumbItem *thumbitem = qVariantValue<ThumbItem *>(item->GetData());
00507 
00508     if (!thumbitem)
00509         return;
00510 
00511     // if the selected thumbitem is a Media Device
00512     // attempt to mount it if it isn't already
00513     if (thumbitem->GetMediaDevice())
00514         handled = HandleMediaDeviceSelect(thumbitem);
00515 
00516     if (!handled && thumbitem->IsDir())
00517     {
00518         m_history.push_back(m_imageList->GetCurrentPos());
00519         LoadDirectory(thumbitem->GetPath());
00520 
00521         handled = true;
00522     }
00523 
00524     if (!handled)
00525         HandleImageSelect("SELECT");
00526 }
00527 
00528 bool IconView::HandleMediaDeviceSelect(ThumbItem *item)
00529 {
00530     MediaMonitor *mon = MediaMonitor::GetMediaMonitor();
00531     if (mon && mon->ValidateAndLock(item->GetMediaDevice()))
00532     {
00533         m_currDevice = item->GetMediaDevice();
00534 
00535 #ifdef _WIN32
00536         LoadDirectory(m_currDevice->getDevicePath());
00537 #else
00538         if (!m_currDevice->isMounted(false))
00539             m_currDevice->mount();
00540 
00541         item->SetPath(m_currDevice->getMountPath(), true);
00542 
00543         connect(m_currDevice,
00544                 SIGNAL(statusChanged(MythMediaStatus,
00545                                      MythMediaDevice*)),
00546                 SLOT(mediaStatusChanged(MythMediaStatus,
00547                                         MythMediaDevice*)));
00548 
00549         LoadDirectory(m_currDevice->getMountPath());
00550 #endif
00551 
00552         mon->Unlock(m_currDevice);
00553     }
00554     else
00555     {
00556         // device was removed
00557         QString msg = tr("Error") + '\n' +
00558                 tr("The selected device is no longer available");
00559         ShowOkPopup(msg, this, SLOT(HandleShowDevices()));
00560     }
00561 
00562     return true;
00563 }
00564 
00565 void IconView::HandleSlideShow(void)
00566 {
00567     HandleImageSelect("SLIDESHOW");
00568 
00569     SetFocusWidget(m_imageList);
00570 }
00571 
00572 void IconView::HandleRandomShow(void)
00573 {
00574     HandleImageSelect("RANDOMSHOW");
00575 
00576     SetFocusWidget(m_imageList);
00577 }
00578 
00579 bool IconView::HandleImageSelect(const QString &action)
00580 {
00581     ThumbItem *thumbitem = GetCurrentThumb();
00582 
00583     if (!thumbitem || (thumbitem->IsDir() && !m_recurse))
00584         return false;
00585 
00586     int slideShow = ((action == "PLAY" || action == "SLIDESHOW") ? 1 :
00587                      (action == "RANDOMSHOW") ? 2 : 0);
00588 
00589     int pos = m_imageList->GetCurrentPos();
00590 
00591 #ifdef USING_OPENGL
00592     if (m_useOpenGL && QGLFormat::hasOpenGL())
00593     {
00594         GLSDialog gv(m_itemList, &pos,
00595                         slideShow, m_sortorder,
00596                         GetMythMainWindow());
00597         gv.exec();
00598     }
00599     else
00600 #endif
00601     {
00602         SingleView sv(m_itemList, &pos, slideShow, m_sortorder,
00603                       GetMythMainWindow());
00604         sv.exec();
00605     }
00606 
00607     // if the user deleted files while in single view mode
00608     // the cached contents of the directory will be out of
00609     // sync, reload the current directory to refresh the view
00610     LoadDirectory(m_currDir);
00611 
00612     m_imageList->SetItemCurrent(pos);
00613 
00614     return true;
00615 }
00616 
00617 bool IconView::HandleMediaEscape(MediaMonitor *mon)
00618 {
00619     bool handled = false;
00620     QDir curdir(m_currDir);
00621     QList<MythMediaDevice*> removables = mon->GetMedias(MEDIATYPE_DATA);
00622     QList<MythMediaDevice*>::iterator it = removables.begin();
00623     for (; !handled && (it != removables.end()); ++it)
00624     {
00625         if (!mon->ValidateAndLock(*it))
00626             continue;
00627 
00628         if (curdir == QDir((*it)->getMountPath()))
00629         {
00630             HandleShowDevices();
00631 
00632             // Make sure previous devices are visible and selected
00633             ThumbItem *item = NULL;
00634             if (!(*it)->getVolumeID().isEmpty())
00635                 item = m_itemHash.value((*it)->getVolumeID());
00636             else
00637                 item = m_itemHash.value((*it)->getDevicePath());
00638 
00639             if (item)
00640             {
00641                 int pos = m_itemList.indexOf(item);
00642                 m_imageList->SetItemCurrent(pos);
00643             }
00644 
00645             handled = true;
00646         }
00647         else
00648         {
00649             handled = HandleSubDirEscape((*it)->getMountPath());
00650         }
00651 
00652         mon->Unlock(*it);
00653     }
00654 
00655     return handled;
00656 }
00657 
00658 static bool is_subdir(const QDir &parent, const QDir &subdir)
00659 {
00660     QString pstr = QDir::cleanPath(parent.path());
00661     QString cstr = QDir::cleanPath(subdir.path());
00662     bool ret = !cstr.indexOf(pstr);
00663 
00664     return ret;
00665 }
00666 
00667 bool IconView::HandleSubDirEscape(const QString &parent)
00668 {
00669     bool handled = false;
00670 
00671     QDir curdir(m_currDir);
00672     QDir pdir(parent);
00673     if ((curdir != pdir) && is_subdir(pdir, curdir) && !m_history.empty())
00674     {
00675         QString oldDirName = curdir.dirName();
00676         curdir.cdUp();
00677         LoadDirectory(curdir.absolutePath());
00678 
00679         int pos = m_history.back();
00680         m_history.pop_back();
00681         m_imageList->SetItemCurrent(pos);
00682         handled = true;
00683     }
00684 
00685     return handled;
00686 }
00687 
00688 bool IconView::HandleEscape(void)
00689 {
00690 #if 0
00691     LOG(VB_GENERAL, LOG_INFO, LOC + "HandleEscape() " +
00692         QString("showDevices: %1").arg(m_showDevices));
00693 #endif
00694 
00695     bool handled = false;
00696 
00697     // If we are showing the attached devices, ESCAPE should always exit..
00698     if (m_showDevices)
00699     {
00700 #if 0
00701         LOG(VB_GENERAL, LOG_INFO, LOC +
00702             "HandleEscape() exiting on showDevices");
00703 #endif
00704         return false;
00705     }
00706 
00707     // If we are viewing an attached device we should show the attached devices
00708     MediaMonitor *mon = MediaMonitor::GetMediaMonitor();
00709     if (mon && m_currDevice)
00710         handled = HandleMediaEscape(mon);
00711 
00712     // If we are viewing a subdirectory of the gallery directory, we should
00713     // move up the directory tree, otherwise ESCAPE should exit..
00714     if (!handled)
00715         handled = HandleSubDirEscape(m_galleryDir);
00716 
00717 #if 0
00718     LOG(VB_GENERAL, LOG_INFO, LOC + QString("HandleEscape() handled: %1")
00719             .arg(handled));
00720 #endif
00721 
00722     return handled;
00723 }
00724 
00725 void IconView::customEvent(QEvent *event)
00726 {
00727     if (event->type() == ThumbGenEvent::kEventType)
00728     {
00729         ThumbGenEvent *tge = dynamic_cast<ThumbGenEvent *>(event);
00730 
00731         if (!tge)
00732             return;
00733 
00734         ThumbData *td = tge->thumbData;
00735         if (!td)
00736             return;
00737 
00738         ThumbItem *thumbitem = m_itemHash.value(td->fileName);
00739         if (thumbitem)
00740         {
00741             int rotateAngle = thumbitem->GetRotationAngle();
00742 
00743             if (rotateAngle)
00744             {
00745                 QMatrix matrix;
00746                 matrix.rotate(rotateAngle);
00747                 td->thumb = td->thumb.transformed(
00748                     matrix, Qt::SmoothTransformation);
00749             }
00750 
00751             int pos = m_itemList.indexOf(thumbitem);
00752 
00753             LoadThumbnail(thumbitem);
00754 
00755             MythUIButtonListItem *item = m_imageList->GetItemAt(pos);
00756             if (QFile(thumbitem->GetImageFilename()).exists())
00757                 item->SetImage(thumbitem->GetImageFilename());
00758 
00759             if (m_imageList->GetCurrentPos() == pos)
00760                 UpdateImage(item);
00761         }
00762         delete td;
00763     }
00764     else if (event->type() == ChildCountEvent::kEventType)
00765     {
00766         ChildCountEvent *cce = dynamic_cast<ChildCountEvent *>(event);
00767 
00768         if (!cce)
00769             return;
00770 
00771         ChildCountData *ccd = cce->childCountData;
00772         if (!ccd)
00773             return;
00774 
00775         ThumbItem *thumbitem = m_itemHash.value(ccd->fileName);
00776         if (thumbitem)
00777         {
00778             int pos = m_itemList.indexOf(thumbitem);
00779             MythUIButtonListItem *item = m_imageList->GetItemAt(pos);
00780             if (item)
00781                 item->SetText(QString("%1").arg(ccd->count), "childcount");
00782         }
00783         delete ccd;
00784     }
00785     else if (event->type() == DialogCompletionEvent::kEventType)
00786     {
00787         DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
00788 
00789         QString resultid  = dce->GetId();
00790         int     buttonnum = dce->GetResult();
00791 
00792         if (resultid == "mainmenu")
00793         {
00794             switch (buttonnum)
00795             {
00796                 case 0:
00797                     HandleSlideShow();
00798                     break;
00799                 case 1:
00800                     HandleRandomShow();
00801                     break;
00802                 case 2:
00803                     break;
00804                 case 3:
00805                     break;
00806                 case 4:
00807                     HandleSubMenuFilter();
00808                     break;
00809                 case 5:
00810                     break;
00811                 case 6:
00812                     HandleSettings();
00813                     break;
00814             }
00815         }
00816         else if (resultid == "metadatamenu")
00817         {
00818             switch (buttonnum)
00819             {
00820                 case 0:
00821                     HandleRotateCW();
00822                     break;
00823                 case 1:
00824                     HandleRotateCCW();
00825                     break;
00826             }
00827         }
00828         else if (resultid == "markingmenu")
00829         {
00830             switch (buttonnum)
00831             {
00832                 case 0:
00833                     HandleSelectOne();
00834                     break;
00835                 case 1:
00836                     HandleClearOneMarked();
00837                     break;
00838                 case 2:
00839                     HandleSelectAll();
00840                     break;
00841                 case 3:
00842                     HandleClearMarked();
00843                     break;
00844             }
00845         }
00846         else if (resultid == "filemenu")
00847         {
00848             switch (buttonnum)
00849             {
00850                 case 0:
00851                     HandleShowDevices();
00852                     break;
00853                 case 1:
00854                     HandleEject();
00855                     break;
00856                 case 2:
00857                     HandleImport();
00858                     break;
00859                 case 3:
00860                     HandleCopyHere();
00861                     break;
00862                 case 4:
00863                     HandleMoveHere();
00864                     break;
00865                 case 5:
00866                     HandleDelete();
00867                     break;
00868                 case 6:
00869                     HandleMkDir();
00870                     break;
00871                 case 7:
00872                     HandleRename();
00873                     break;
00874             }
00875         }
00876 
00877         m_menuPopup = NULL;
00878 
00879     }
00880 
00881 }
00882 
00883 void IconView::reloadData()
00884 {
00885     LoadDirectory(m_galleryDir);
00886 }
00887 
00888 void IconView::HandleMainMenu(void)
00889 {
00890     QString label = tr("Gallery Options");
00891 
00892     MythMenu *menu = new MythMenu(label, this, "mainmenu");
00893 
00894     menu->AddItem(tr("SlideShow"));
00895     menu->AddItem(tr("Random"));
00896     menu->AddItem(tr("Meta Data Options"), NULL, CreateMetadataMenu());
00897     menu->AddItem(tr("Marking Options"), NULL, CreateMarkingMenu());
00898     menu->AddItem(tr("Filter / Sort..."));
00899     menu->AddItem(tr("File Options"), NULL, CreateFileMenu());
00900     menu->AddItem(tr("Settings..."));
00901 //     if (m_showDevices)
00902 //     {
00903 //         QDir d(m_currDir);
00904 //         if (!d.exists())
00905 //             m_currDir = m_galleryDir;
00906 //
00907 //         LoadDirectory(m_currDir);
00908 //         m_showDevices = false;
00909 //     }
00910 
00911     m_menuPopup = new MythDialogBox(menu, m_popupStack, "mythgallerymenupopup");
00912 
00913     if (!m_menuPopup->Create())
00914     {
00915         delete m_menuPopup;
00916         m_menuPopup = NULL;
00917         return;
00918     }
00919 
00920     m_popupStack->AddScreen(m_menuPopup);
00921 }
00922 
00923 MythMenu* IconView::CreateMetadataMenu(void)
00924 {
00925     QString label = tr("Metadata Options");
00926 
00927     MythMenu *menu = new MythMenu(label, this, "metadatamenu");
00928 
00929     menu->AddItem(tr("Rotate CW"));
00930     menu->AddItem(tr("Rotate CCW"));
00931 
00932     return menu;
00933 }
00934 
00935 MythMenu* IconView::CreateMarkingMenu(void)
00936 {
00937     QString label = tr("Marking Options");
00938 
00939     MythMenu *menu = new MythMenu(label, this, "markingmenu");
00940 
00941     menu->AddItem(tr("Select One"));
00942     menu->AddItem(tr("Clear One Marked"));
00943     menu->AddItem(tr("Select All"));
00944     menu->AddItem(tr("Clear Marked"));
00945 
00946     return menu;
00947 }
00948 
00949 void IconView::HandleSubMenuFilter(void)
00950 {
00951     MythScreenStack *mainStack = GetScreenStack();
00952 
00953     GalleryFilterDialog *filterdialog =
00954         new GalleryFilterDialog(mainStack, "galleryfilter", m_galleryFilter);
00955 
00956     if (filterdialog->Create())
00957         mainStack->AddScreen(filterdialog);
00958 
00959     connect(filterdialog, SIGNAL(filterChanged()), SLOT(reloadData()));
00960 }
00961 
00962 MythMenu* IconView::CreateFileMenu(void)
00963 {
00964     QString label = tr("File Options");
00965 
00966     MythMenu *menu = new MythMenu(label, this, "filemenu");
00967 
00968     menu->AddItem(tr("Show Devices"));
00969     menu->AddItem(tr("Eject"));
00970     menu->AddItem(tr("Import"));
00971     menu->AddItem(tr("Copy here"));
00972     menu->AddItem(tr("Move here"));
00973     menu->AddItem(tr("Delete"));
00974     menu->AddItem(tr("Create folder"));
00975     menu->AddItem(tr("Rename"));
00976 
00977     return menu;
00978 }
00979 
00980 void IconView::HandleRotateCW(void)
00981 {
00982     ThumbItem *thumbitem = GetCurrentThumb();
00983 
00984     if (!thumbitem || thumbitem->IsDir())
00985         return;
00986 
00987     int rotAngle = thumbitem->GetRotationAngle();
00988 
00989     rotAngle += 90;
00990 
00991     if (rotAngle >= 360)
00992         rotAngle -= 360;
00993 
00994     if (rotAngle < 0)
00995         rotAngle += 360;
00996 
00997     thumbitem->SetRotationAngle(rotAngle);
00998 }
00999 
01000 void IconView::HandleRotateCCW(void)
01001 {
01002     ThumbItem *thumbitem = GetCurrentThumb();
01003 
01004     if (!thumbitem || thumbitem->IsDir())
01005         return;
01006 
01007     int rotAngle = thumbitem->GetRotationAngle();
01008 
01009     rotAngle -= 90;
01010 
01011     if (rotAngle >= 360)
01012         rotAngle -= 360;
01013 
01014     if (rotAngle < 0)
01015         rotAngle += 360;
01016 
01017     thumbitem->SetRotationAngle(rotAngle);
01018 }
01019 
01020 void IconView::HandleDeleteCurrent(void)
01021 {
01022     ThumbItem *thumbitem = GetCurrentThumb();
01023 
01024     if (!thumbitem)
01025         return;
01026 
01027     QString title = tr("Delete Current File or Folder");
01028     QString msg = (thumbitem->IsDir()) ?
01029         tr("Deleting 1 folder, including any subfolders and files.") :
01030         tr("Deleting 1 image.");
01031 
01032     ShowOkPopup(title + '\n' + msg, this, SLOT(DoDeleteCurrent(bool)), true);
01033 }
01034 
01035 void IconView::DoDeleteCurrent(bool doDelete)
01036 {
01037     if (doDelete)
01038     {
01039         ThumbItem *thumbitem = GetCurrentThumb();
01040 
01041         if (!thumbitem)
01042             return;
01043 
01044         QFileInfo fi;
01045         fi.setFile(thumbitem->GetPath());
01046         GalleryUtil::Delete(fi);
01047 
01048         LoadDirectory(m_currDir);
01049     }
01050 }
01051 
01052 void IconView::HandleSettings(void)
01053 {
01054     GallerySettings settings;
01055     settings.exec();
01056     gCoreContext->ClearSettingsCache();
01057 
01058     // reload settings
01059     m_showcaption = gCoreContext->GetNumSetting("GalleryOverlayCaption", 0);
01060     m_sortorder   = gCoreContext->GetNumSetting("GallerySortOrder", 0);
01061     m_useOpenGL   = gCoreContext->GetNumSetting("SlideshowUseOpenGL", 0);
01062     m_recurse     = gCoreContext->GetNumSetting("GalleryRecursiveSlideshow", 0);
01063     m_paths       = gCoreContext->GetSetting("GalleryImportDirs").split(":");
01064 
01065     // reload directory
01066     MediaMonitor *mon = MediaMonitor::GetMediaMonitor();
01067     if (m_currDevice && mon && mon->ValidateAndLock(m_currDevice))
01068     {
01069 #ifdef _WIN32
01070         LoadDirectory(m_currDevice->getDevicePath());
01071 #else
01072         LoadDirectory(m_currDevice->getMountPath());
01073 #endif
01074         mon->Unlock(m_currDevice);
01075     }
01076     else
01077     {
01078         m_currDevice = NULL;
01079         LoadDirectory(m_galleryDir);
01080     }
01081 
01082     SetFocusWidget(m_imageList);
01083 }
01084 
01085 void IconView::HandleEject(void)
01086 {
01087     MediaMonitor::ejectOpticalDisc();
01088 }
01089 
01090 void IconView::HandleImport(void)
01091 {
01092     QFileInfo path;
01093     QDir importdir;
01094 
01095 #if 0
01096     DialogBox *importDlg = new DialogBox(GetMythMainWindow(),
01097                                          tr("Import pictures?"));
01098 
01099     importDlg->AddButton(tr("No"));
01100     importDlg->AddButton(tr("Yes"));
01101     DialogCode code = importDlg->exec();
01102     importDlg->deleteLater();
01103     if (kDialogCodeButton1 != code)
01104         return;
01105 #endif
01106 
01107     // Makes import directory samba/windows friendly (no colon)
01108     QString idirname = m_currDir + "/" +
01109         QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss");
01110 
01111     importdir.mkdir(idirname);
01112     importdir.setPath(idirname);
01113 
01114     for (QStringList::const_iterator it = m_paths.begin();
01115          it != m_paths.end(); ++it)
01116     {
01117         path.setFile(*it);
01118         if (path.isDir() && path.isReadable())
01119         {
01120             ImportFromDir(*it, importdir.absolutePath());
01121         }
01122 #if 0
01123         else if (path.isFile() && path.isExecutable())
01124         {
01125             // TODO this should not be enabled by default!!!
01126             QString cmd = *it + " " + importdir.absolutePath();
01127             LOG(VB_GENERAL, LOG_INFO, LOC + QString("Executing %1").arg(cmd));
01128             myth_system(cmd);
01129         }
01130 #endif
01131         else
01132         {
01133             LOG(VB_GENERAL, LOG_ERR, LOC +
01134                 QString("Could not read or execute %1").arg(*it));
01135         }
01136     }
01137 
01138     importdir.refresh();
01139     if (importdir.count() == 0)
01140     {
01141 #if 0
01142         DialogBox *nopicsDlg = new DialogBox(GetMythMainWindow(),
01143                                              tr("Nothing found to import"));
01144 
01145         nopicsDlg->AddButton(tr("OK"));
01146         nopicsDlg->exec();
01147         nopicsDlg->deleteLater();
01148 #endif
01149 
01150         return;
01151     }
01152 
01153     LoadDirectory(m_currDir);
01154 }
01155 
01156 void IconView::HandleShowDevices(void)
01157 {
01158     MediaMonitor *mon = MediaMonitor::GetMediaMonitor();
01159 #ifndef _WIN32
01160     if (m_currDevice && mon && mon->ValidateAndLock(m_currDevice))
01161     {
01162         m_currDevice->disconnect(this);
01163         mon->Unlock(m_currDevice);
01164     }
01165     else
01166         m_currDir = m_galleryDir;
01167 #endif
01168 
01169     m_currDevice = NULL;
01170 
01171     m_showDevices = true;
01172 
01173     while (!m_itemList.isEmpty())
01174         delete m_itemList.takeFirst();
01175 
01176     m_itemHash.clear();
01177     m_imageList->Reset();
01178 
01179     m_thumbGen->cancel();
01180     m_childCountThread->cancel();
01181 
01182     // add gallery directory
01183     ThumbItem *item = new ThumbItem("Gallery", m_galleryDir, true);
01184     m_itemList.append(item);
01185     m_itemHash.insert(item->GetName(), item);
01186 
01187     if (mon)
01188     {
01189         MythMediaType type = MythMediaType(MEDIATYPE_DATA | MEDIATYPE_MGALLERY);
01190         QList<MythMediaDevice*> removables = mon->GetMedias(type);
01191         QList<MythMediaDevice*>::Iterator it = removables.begin();
01192         for (; it != removables.end(); ++it)
01193         {
01194             if (mon->ValidateAndLock(*it))
01195             {
01196                 item = new ThumbItem(
01197                     (*it)->getVolumeID().isEmpty() ?
01198                     (*it)->getDevicePath() : (*it)->getVolumeID(),
01199                     (*it)->getMountPath(), true, *it);
01200 
01201                 m_itemList.append(item);
01202                 m_itemHash.insert(item->GetName(), item);
01203 
01204                 mon->Unlock(*it);
01205             }
01206         }
01207     }
01208 
01209     ThumbItem *thumbitem;
01210     for (int x = 0; x < m_itemList.size(); x++)
01211     {
01212         thumbitem = m_itemList.at(x);
01213 
01214         thumbitem->InitCaption(m_showcaption);
01215         MythUIButtonListItem* item =
01216             new MythUIButtonListItem(m_imageList, thumbitem->GetCaption(), 0,
01217                                      true, MythUIButtonListItem::NotChecked);
01218         item->SetData(qVariantFromValue(thumbitem));
01219     }
01220 
01221     // exit from menu on show devices action..
01222     SetFocusWidget(m_imageList);
01223 }
01224 
01225 void IconView::HandleCopyHere(void)
01226 {
01227     CopyMarkedFiles(false);
01228     HandleClearMarked();
01229 }
01230 
01231 void IconView::HandleMoveHere(void)
01232 {
01233     CopyMarkedFiles(true);
01234     HandleClearMarked();
01235 }
01236 
01237 void IconView::HandleDelete(void)
01238 {
01239     if (m_itemMarked.isEmpty())
01240         HandleDeleteCurrent();
01241     else
01242         HandleDeleteMarked();
01243 }
01244 
01245 void IconView::HandleDeleteMarked(void)
01246 {
01247     QString msg = /*tr("Delete Marked Files") + "\n\n" +*/
01248             tr("Deleting %1 images and folders, including "
01249                "any subfolders and files.").arg(m_itemMarked.count());
01250     ShowOkPopup(msg, this, SLOT(DoDeleteMarked(bool)), true);
01251 }
01252 
01253 void IconView::DoDeleteMarked(bool doDelete)
01254 {
01255     if (doDelete)
01256     {
01257         QStringList::iterator it;
01258         QFileInfo fi;
01259 
01260         for (it = m_itemMarked.begin(); it != m_itemMarked.end(); ++it)
01261         {
01262             fi.setFile(*it);
01263 
01264             GalleryUtil::Delete(fi);
01265         }
01266 
01267         m_itemMarked.clear();
01268 
01269         LoadDirectory(m_currDir);
01270     }
01271 }
01272 
01273 void IconView::HandleClearOneMarked(void)
01274 {
01275     MythUIButtonListItem *item = m_imageList->GetItemCurrent();
01276     if (!item)
01277         return;
01278     item->setChecked(MythUIButtonListItem::NotChecked);
01279 }
01280 
01281 void IconView::HandleSelectOne(void)
01282 {
01283     MythUIButtonListItem *item = m_imageList->GetItemCurrent();
01284     if (!item)
01285         return;
01286     item->setChecked(MythUIButtonListItem::FullChecked);
01287 }
01288 
01289 void IconView::HandleClearMarked(void)
01290 {
01291     m_itemMarked.clear();
01292     m_imageList->SetAllChecked(MythUIButtonListItem::NotChecked);
01293 }
01294 
01295 void IconView::HandleSelectAll(void)
01296 {
01297     ThumbItem *item;
01298     for (int x = 0; x < m_itemList.size(); x++)
01299     {
01300         item = m_itemList.at(x);
01301 
01302         if (!m_itemMarked.contains(item->GetPath()))
01303             m_itemMarked.append(item->GetPath());
01304     }
01305 
01306     m_imageList->SetAllChecked(MythUIButtonListItem::FullChecked);
01307 }
01308 
01309 void IconView::HandleMkDir(void)
01310 {
01311     QString folderName = tr("New Folder");
01312 
01313     QString message = tr("Create New Folder");
01314 
01315     MythTextInputDialog *dialog = new MythTextInputDialog(m_popupStack, message);
01316 
01317     if (dialog->Create())
01318        m_popupStack->AddScreen(dialog);
01319 
01320      connect(dialog, SIGNAL(haveResult(QString)),
01321             SLOT(DoMkDir(QString)), Qt::QueuedConnection);
01322 }
01323 
01324 void IconView::DoMkDir(QString folderName)
01325 {
01326     QDir cdir(m_currDir);
01327     cdir.mkdir(folderName);
01328 
01329     LoadDirectory(m_currDir);
01330 }
01331 
01332 
01333 void IconView::HandleRename(void)
01334 {
01335     ThumbItem *thumbitem = GetCurrentThumb();
01336 
01337     if (!thumbitem)
01338         return;
01339 
01340     QString folderName = thumbitem->GetName();
01341 
01342     QString message = tr("Rename");
01343 
01344     MythTextInputDialog *dialog = new MythTextInputDialog(m_popupStack,
01345             message, FilterNone, false, folderName);
01346 
01347     if (dialog->Create())
01348        m_popupStack->AddScreen(dialog);
01349 
01350      connect(dialog, SIGNAL(haveResult(QString)),
01351             SLOT(DoRename(QString)), Qt::QueuedConnection);
01352 }
01353 
01354 void IconView::DoRename(QString folderName)
01355 {
01356     if (folderName.isEmpty() || folderName == "." || folderName == "..")
01357         return;
01358 
01359     ThumbItem *thumbitem = GetCurrentThumb();
01360 
01361     if (!thumbitem)
01362         return;
01363 
01364     if (!GalleryUtil::Rename(m_currDir, thumbitem->GetName(), folderName))
01365     {
01366         QString msg;
01367         if (thumbitem->IsDir())
01368             msg = tr("Failed to rename folder");
01369         else
01370             msg = tr("Failed to rename file");
01371 
01372         ShowOkPopup(msg, NULL, NULL);
01373 
01374         return;
01375     }
01376 
01377     LoadDirectory(m_currDir);
01378 }
01379 
01380 void IconView::ImportFromDir(const QString &fromDir, const QString &toDir)
01381 {
01382     QDir d(fromDir);
01383 
01384     if (!d.exists())
01385         return;
01386 
01387     d.setNameFilters(GalleryUtil::GetMediaFilter());
01388     d.setSorting((QDir::SortFlag)m_sortorder);
01389     d.setFilter(QDir::Files       | QDir::AllDirs |
01390                 QDir::NoSymLinks  | QDir::Readable);
01391     QFileInfoList list = d.entryInfoList();
01392     QFileInfoList::const_iterator it = list.begin();
01393     const QFileInfo *fi;
01394 
01395     while (it != list.end())
01396     {
01397         fi = &(*it);
01398         ++it;
01399         if (fi->fileName() == "." || fi->fileName() == "..")
01400             continue;
01401 
01402         if (fi->isDir())
01403         {
01404             QString newdir(toDir + "/" + fi->fileName());
01405             d.mkdir(newdir);
01406             ImportFromDir(fi->absoluteFilePath(), newdir);
01407         }
01408         else
01409         {
01410             LOG(VB_GENERAL, LOG_INFO, LOC + QString("Copying %1 to %2")
01411                     .arg(fi->absoluteFilePath())
01412                     .arg(toDir));
01413 
01414             // TODO FIXME, we shouldn't need a myth_system call here
01415             QString cmd = QString("cp \"%1\" \"%2\"")
01416                 .arg(fi->absoluteFilePath()).arg(toDir);
01417             cmd = QString(cmd.toLocal8Bit().constData());
01418             myth_system(cmd);
01419         }
01420     }
01421 }
01422 
01423 void IconView::CopyMarkedFiles(bool move)
01424 {
01425     if (m_itemMarked.isEmpty())
01426         return;
01427 
01428     QString msg = (move) ?
01429         tr("Moving marked images...") : tr("Copying marked images...");
01430 
01431     MythUIProgressDialog *copy_progress = new MythUIProgressDialog(msg,
01432                                                     m_popupStack,
01433                                                     "copyprogressdialog");
01434 
01435     if (copy_progress->Create())
01436     {
01437         m_popupStack->AddScreen(copy_progress, false);
01438         copy_progress->SetTotal(m_itemMarked.count());
01439     }
01440     else
01441     {
01442         delete copy_progress;
01443         copy_progress = NULL;
01444     }
01445 
01446     FileCopyThread *filecopy = new FileCopyThread(this, move);
01447     int progress = -1;
01448     filecopy->start();
01449 
01450     while (!filecopy->isFinished())
01451     {
01452         if (copy_progress)
01453         {
01454             if (progress != filecopy->GetProgress())
01455             {
01456                 progress = filecopy->GetProgress();
01457                 copy_progress->SetProgress(progress);
01458             }
01459         }
01460 
01461         usleep(500);
01462         qApp->processEvents();
01463     }
01464 
01465     delete filecopy;
01466 
01467     if (copy_progress)
01468         copy_progress->Close();
01469 
01470     LoadDirectory(m_currDir);
01471 }
01472 
01473 void IconView::mediaStatusChanged(MythMediaStatus oldStatus,
01474                                   MythMediaDevice *pMedia)
01475 {
01476     (void) oldStatus;
01477     if (m_currDevice == pMedia)
01478     {
01479         HandleShowDevices();
01480 
01481         // UpdateText();
01482     }
01483 }
01484 
01485 ThumbItem *IconView::GetCurrentThumb(void)
01486 {
01487     MythUIButtonListItem *item = m_imageList->GetItemCurrent();
01488     if (item)
01489         return qVariantValue<ThumbItem *>(item->GetData());
01490     return NULL;
01491 }
01492 
01494 
01495 ChildCountThread::ChildCountThread(QObject *parent) :
01496     MThread("ChildCountThread"), m_parent(parent)
01497 {
01498 }
01499 
01500 ChildCountThread::~ChildCountThread()
01501 {
01502     cancel();
01503     wait();
01504 }
01505 
01506 void ChildCountThread::addFile(const QString& filePath)
01507 {
01508     m_mutex.lock();
01509     m_fileList.append(filePath);
01510     m_mutex.unlock();
01511 }
01512 
01513 void ChildCountThread::cancel()
01514 {
01515     m_mutex.lock();
01516     m_fileList.clear();
01517     m_mutex.unlock();
01518 }
01519 
01520 void ChildCountThread::run()
01521 {
01522     RunProlog();
01523 
01524     while (moreWork())
01525     {
01526         QString file;
01527 
01528         m_mutex.lock();
01529         file = m_fileList.first();
01530         if (!m_fileList.isEmpty())
01531             m_fileList.pop_front();
01532         m_mutex.unlock();
01533 
01534         if (file.isEmpty())
01535             continue;
01536         int count = getChildCount(file);
01537 
01538         ChildCountData *ccd = new ChildCountData;
01539         ccd->fileName  = file.section('/', -1);
01540         ccd->count     = count;
01541 
01542         // inform parent we have got a count ready for it
01543         QApplication::postEvent(m_parent, new ChildCountEvent(ccd));
01544     }
01545 
01546     RunEpilog();
01547 }
01548 
01549 bool ChildCountThread::moreWork()
01550 {
01551     bool result;
01552     m_mutex.lock();
01553     result = !m_fileList.isEmpty();
01554     m_mutex.unlock();
01555     return result;
01556 }
01557 
01558 int ChildCountThread::getChildCount(const QString &filepath)
01559 {
01560     QDir d(filepath);
01561 
01562     bool isGallery;
01563     QFileInfoList gList = d.entryInfoList(QStringList("serial*.dat"),
01564                                           QDir::Files);
01565     isGallery = (gList.count() != 0);
01566 
01567     QFileInfoList list = d.entryInfoList(GalleryUtil::GetMediaFilter(),
01568                                          QDir::Files | QDir::AllDirs);
01569 
01570     if (list.isEmpty())
01571         return 0;
01572 
01573     QFileInfoList::const_iterator it = list.begin();
01574     const QFileInfo *fi;
01575 
01576     int count = 0;
01577     while (it != list.end())
01578     {
01579         fi = &(*it);
01580         ++it;
01581         if (fi->fileName() == "." || fi->fileName() == "..")
01582             continue;
01583 
01584         // remove these already-resized pictures.
01585         if (isGallery && (
01586                 (fi->fileName().indexOf(".thumb.") > 0) ||
01587                 (fi->fileName().indexOf(".sized.") > 0) ||
01588                 (fi->fileName().indexOf(".highlight.") > 0)))
01589             continue;
01590 
01591         count++;
01592     }
01593 
01594     return count;
01595 }
01596 
01597 /*
01598  * vim:ts=4:sw=4:ai:et:si:sts=4
01599  */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends