|
MythTV
0.26-pre
|
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 */
1.7.6.1