30 #include <QApplication> 57 #define LOC QString("IconView: ") 60 (QEvent::Type) QEvent::registerEventType();
76 MThread(
"FileCopy"), m_move(move), m_parent(parent), m_progress(0)
84 QStringList::iterator it;
108 MThread(
"import"), m_command(cmd)
115 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Executing %1").arg(
m_command));
125 m_galleryDir(galleryDir),
127 m_imageList(nullptr),
128 m_captionText(nullptr), m_crumbsText(nullptr),
129 m_positionText(nullptr), m_noImagesText(nullptr),
130 m_selectedImage(nullptr), m_menuPopup(nullptr),
131 m_popupStack(nullptr),
133 m_currDevice(initialDevice),
145 if (!dir.exists() || !dir.isReadable())
147 m_errorStr = tr(
"MythGallery Directory '%1' does not exist " 191 LOG(VB_GENERAL, LOG_ERR,
"Cannot load screen 'gallery'");
241 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LoadDirectory called with " +
242 QString(
"non-existant directory: '%1'").arg(dir));
270 item->
SetData(qVariantFromValue(thumbitem));
271 if (thumbitem->
IsDir())
312 QDir subdir(item->
GetPath(),
"*.highlight.*",
313 QDir::Name, QDir::Files);
315 if (subdir.count() > 0)
318 QFileInfoList::const_iterator it = subdir.entryInfoList().begin();
319 if (it != subdir.entryInfoList().end())
321 imagePath = it->absoluteFilePath();
328 int firstDot = fn.indexOf(
'.');
331 fn.insert(firstDot,
".thumb");
332 imagePath = QString(
"%1/%2").arg(
m_currDir).arg(fn);
336 canLoadGallery = !(QFile(imagePath).exists());
340 imagePath = QString(
"%1%2.jpg")
406 QString path = thumbitem->
GetPath();
408 path.replace(
"/",
" > ");
416 caption = (caption.isNull()) ?
"" : caption;
428 QString selectedimage;
432 selectedimage = (selectedimage.isNull()) ?
"" : selectedimage;
447 for (
int i = 0; i < actions.size() && !handled; i++)
449 QString
action = actions[i];
456 else if (
action ==
"ROTLEFT")
458 else if (
action ==
"DELETE")
460 else if (
action ==
"EDIT")
462 else if (
action ==
"MARK")
481 else if (
action ==
"SLIDESHOW")
483 else if (
action ==
"RANDOMSHOW")
485 else if (
action ==
"SEASONALSHOW")
500 else if (
action ==
"MENU")
514 bool handled =
false;
526 if (!handled && thumbitem->
IsDir())
567 QString msg = tr(
"Error") +
'\n' +
568 tr(
"The selected device is no longer available");
603 int slideShow = ((
action ==
"PLAY" ||
action ==
"SLIDESHOW") ? 1 :
604 (
action ==
"RANDOMSHOW") ? 2 :
605 (
action ==
"SEASONALSHOW" ? 3 : 0));
637 bool handled =
false;
640 QList<MythMediaDevice*>::iterator it = removables.begin();
641 for (; !handled && (it != removables.end()); ++it)
646 if (curdir == QDir((*it)->getMountPath()))
652 if (!(*it)->getVolumeID().isEmpty())
653 item =
m_itemHash.value((*it)->getVolumeID());
655 item =
m_itemHash.value((*it)->getDevicePath());
676 static bool is_subdir(
const QDir &parent,
const QDir &subdir)
678 QString pstr = QDir::cleanPath(parent.path());
679 QString cstr = QDir::cleanPath(subdir.path());
680 bool ret = !cstr.indexOf(pstr);
687 bool handled =
false;
693 QString oldDirName = curdir.dirName();
709 LOG(VB_GENERAL, LOG_INFO,
LOC +
"HandleEscape() " +
713 bool handled =
false;
719 LOG(VB_GENERAL, LOG_INFO,
LOC +
720 "HandleEscape() exiting on showDevices");
736 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"HandleEscape() handled: %1")
764 matrix.rotate(rotateAngle);
766 matrix, Qt::SmoothTransformation);
799 item->
SetText(QString(
"%1").arg(ccd->
count),
"childcount");
807 QString resultid = dce->
GetId();
808 int resultdata = dce->
GetData().toInt();
810 if (resultid ==
"mainmenu")
837 else if (resultid ==
"metadatamenu")
849 else if (resultid ==
"markingmenu")
867 else if (resultid ==
"filemenu")
911 QString label = tr(
"Gallery Options");
917 menu->AddItem(tr(
"SlideShow"),
nullptr);
918 menu->AddItem(tr(
"Random"), 1);
920 menu->AddItem(tr(
"Seasonal"), 7);
921 #endif // EXIF_SUPPORT 926 menu->AddItem(tr(
"Filter / Sort..."), 4);
928 menu->AddItem(tr(
"Settings..."), 6);
953 QString label = tr(
"Metadata Options");
957 menu->AddItem(tr(
"Rotate CW"),
nullptr);
958 menu->AddItem(tr(
"Rotate CCW"), 1);
965 QString label = tr(
"Marking Options");
969 menu->AddItem(tr(
"Select One"),
nullptr);
970 menu->AddItem(tr(
"Clear One Marked"), 1);
971 menu->AddItem(tr(
"Select All"), 2);
972 menu->AddItem(tr(
"Clear Marked"), 3);
984 if (filterdialog->
Create())
987 connect(filterdialog, SIGNAL(filterChanged()), SLOT(
reloadData()));
992 QString label = tr(
"File Options");
996 menu->AddItem(tr(
"Show Devices"),
nullptr);
997 menu->AddItem(tr(
"Eject"), 1);
998 menu->AddItem(tr(
"Import"), 2);
1002 menu->AddItem(tr(
"Copy here"), 3);
1003 menu->AddItem(tr(
"Move here"), 4);
1007 menu->AddItem(tr(
"Delete"), 5);
1009 menu->AddItem(tr(
"Create folder"), 6);
1012 menu->AddItem(tr(
"Rename"), 7);
1021 if (!thumbitem || thumbitem->
IsDir())
1028 if (rotAngle >= 360)
1041 if (!thumbitem || thumbitem->
IsDir())
1048 if (rotAngle >= 360)
1064 QString title = tr(
"Delete Current File or Folder");
1065 QString msg = (thumbitem->
IsDir()) ?
1066 tr(
"Deleting 1 folder, including any subfolders and files.") :
1067 tr(
"Deleting 1 image.");
1087 fi.setFile(thumbitem->
GetPath());
1159 importdir.mkdir(idirname);
1160 importdir.setPath(idirname);
1162 for (QStringList::const_iterator it =
m_paths.begin();
1166 if (path.isDir() && path.isReadable())
1170 else if (path.isFile() && path.isExecutable())
1174 QString cmd = *it +
" " + importdir.absolutePath();
1180 "importbusydialog");
1195 while (!import->isFinished())
1198 qApp->processEvents();
1208 ShowOkPopup(tr(
"Found an import script (%1) but running them has been disabled in the settings!")
1210 importdir.rmdir(importdir.absolutePath());
1216 LOG(VB_GENERAL, LOG_ERR,
LOC +
1217 QString(
"Could not read or execute %1").arg(*it));
1219 ShowOkPopup(tr(
"Could not read or execute %1").arg(*it));
1223 importdir.setFilter(QDir::Files | QDir::Readable | QDir::NoDotAndDotDot);
1224 importdir.refresh();
1225 if (importdir.count() == 0)
1228 importdir.rmdir(importdir.absolutePath());
1232 ShowOkPopup(tr(
"Found %n image(s)",
"", importdir.count()));
1272 QList<MythMediaDevice*>::Iterator it = removables.begin();
1273 for (; it != removables.end(); ++it)
1278 (*it)->getVolumeID().isEmpty() ?
1279 (*it)->getDevicePath() : (*it)->getVolumeID(),
1280 (*it)->getMountPath(),
true, *it);
1298 menuitem->
SetData(qVariantFromValue(item3));
1328 tr(
"Deleting %1 images and folders, including " 1329 "any subfolders and files.").arg(
m_itemMarked.count());
1337 QStringList::iterator it;
1390 QString folderName = tr(
"New Folder");
1392 QString message = tr(
"Create New Folder");
1399 connect(dialog, SIGNAL(haveResult(QString)),
1400 SLOT(
DoMkDir(QString)), Qt::QueuedConnection);
1406 cdir.mkdir(folderName);
1419 QString folderName = thumbitem->
GetName();
1421 QString message = tr(
"Rename");
1429 connect(dialog, SIGNAL(haveResult(QString)),
1430 SLOT(
DoRename(QString)), Qt::QueuedConnection);
1435 if (folderName.isEmpty() || folderName ==
"." || folderName ==
"..")
1456 if (thumbitem->
IsDir())
1457 msg = tr(
"Failed to rename folder");
1459 msg = tr(
"Failed to rename file");
1480 d.setFilter(QDir::Files | QDir::AllDirs |
1481 QDir::NoSymLinks | QDir::Readable |
1482 QDir::NoDotAndDotDot);
1483 QFileInfoList list =
d.entryInfoList();
1484 QFileInfoList::const_iterator it = list.begin();
1486 while (it != list.end())
1488 const QFileInfo *fi = &(*it);
1493 QString newdir(toDir +
"/" + fi->fileName());
1499 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Copying %1 to %2")
1500 .arg(fi->absoluteFilePath())
1504 QString cmd = QString(
"cp \"%1\" \"%2\"")
1505 .arg(fi->absoluteFilePath()).arg(toDir);
1506 cmd = QString(cmd.toLocal8Bit().constData());
1517 QString msg = (move) ?
1518 tr(
"Moving marked images...") : tr(
"Copying marked images...");
1522 "copyprogressdialog");
1524 if (copy_progress->
Create())
1531 delete copy_progress;
1532 copy_progress =
nullptr;
1551 qApp->processEvents();
1557 copy_progress->
Close();
1585 MThread(
"ChildCountThread"), m_parent(parent)
1628 ccd->
fileName = file.section(
'/', -1);
1652 QFileInfoList gList =
d.entryInfoList(QStringList(
"serial*.dat"),
1654 isGallery = (gList.count() != 0);
1657 QDir::Files | QDir::AllDirs |
1658 QDir::NoDotAndDotDot);
1663 QFileInfoList::const_iterator it = list.begin();
1666 while (it != list.end())
1668 const QFileInfo *fi = &(*it);
1673 (fi->fileName().indexOf(
".thumb.") > 0) ||
1674 (fi->fileName().indexOf(
".sized.") > 0) ||
1675 (fi->fileName().indexOf(
".highlight.") > 0)))
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
void HandleRotateCW(void)
void start(QThread::Priority=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
QString GetCaption(void) const
MythScreenStack * GetScreenStack() const
void UpdateText(MythUIButtonListItem *)
void HandleClearMarked(void)
This is a wrapper around QThread that does several additional things.
void HandleSettings(void)
void HandleSeasonalShow(void)
void HandleCopyHere(void)
bool TranslateKeyPress(const QString &context, QKeyEvent *e, QStringList &actions, bool allowJumps=true)
Get a list of actions for a keypress in the given context.
void mediaStatusChanged(MythMediaStatus oldStatus, MythMediaDevice *pMedia)
void SetProgress(uint count)
bool HandleImageSelect(const QString &action)
MythConfirmationDialog * ShowOkPopup(const QString &message, QObject *parent, const char *slot, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
bool Create(void) override
void HandleItemSelect(MythUIButtonListItem *)
bool Create(void) override
void HandleMoveHere(void)
bool wait(unsigned long time=ULONG_MAX)
Wait for the MThread to exit, with a maximum timeout.
Basic menu dialog, message and a list of options.
void customEvent(QEvent *) override
MythMediaDevice * GetMediaDevice(void)
static bool Rename(const QString &currDir, const QString &oldName, const QString &newName)
void run() override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
virtual void SetText(const QString &text)
friend class FileCopyThread
bool HandleMediaDeviceSelect(ThumbItem *item)
static bool LoadDirectory(ThumbList &itemList, const QString &dir, const GalleryFilter &flt, bool recurse, ThumbHash *itemHash, ThumbGenerator *thumbGen)
int getChildCount(const QString &fileName)
MythScreenStack * GetStack(const QString &stackname)
void HandleSelectAll(void)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
MythScreenStack * GetMainStack()
void HandleShowDevices(void)
MythUIText * m_positionText
void HandleDeleteCurrent(void)
static MythThemedMenu * menu
ChildCountData * childCountData
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
void BuildFocusList(void)
MythScreenStack * m_popupStack
bool HandleSubDirEscape(const QString &parent)
void LoadDirectory(const QString &dir)
void HandleSubMenuFilter(void)
void addFile(const QString &fileName)
MythUIButtonList * m_imageList
ThumbItem * GetCurrentThumb(void)
void CopyMarkedFiles(bool move=false)
static bool CopyMove(const QFileInfo &src, QFileInfo &dst, bool move)
void SetTotal(uint total)
FileCopyThread(IconView *parent, bool move)
bool Create(void) override
static int run(MythMediaDevice *dev=nullptr, bool startRandomShow=false)
virtual void SetVisible(bool visible)
IconView(MythScreenStack *parent, const char *name, const QString &galleryDir, MythMediaDevice *initialDevice)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
static QStringList GetMediaFilter(void)
QString GetName(void) const
long GetRotationAngle(void)
GalleryFilter * m_galleryFilter
bool Create(void) override
MythUIText * m_crumbsText
static bool Delete(const QFileInfo &file)
MythDialogBox * m_menuPopup
ChildCountThread * m_childCountThread
bool m_allowImportScripts
static const uint16_t * d
virtual MythRect GetArea(void) const
If the object has a minimum area defined, return it, other wise return the default area.
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
QString GetSetting(const QString &key, const QString &defaultval="")
static QString getThumbcacheDir(const QString &inDir)
MythUIText * m_noImagesText
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
bool isRunning(void) const
void run() override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
void HandleClearOneMarked(void)
void HandleSelectOne(void)
void SetImageFilename(const QString &filename)
void DoDeleteCurrent(bool doDelete)
uint myth_system(const QString &command, uint flags, uint timeout)
ImportThread(const QString &cmd)
MythMenu * CreateFileMenu(void)
void SetPath(const QString &path, bool isDir)
void UpdateImage(MythUIButtonListItem *)
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
MythUIType * GetFocusWidget(void) const
void ReloadSettings(void)
QHash< QString, ThumbItem * > m_itemHash
void HandleMainMenu(void)
MythMainWindow * GetMythMainWindow(void)
void run() override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
MythUIText * m_captionText
void HandleRandomShow(void)
QString GetPath(void) const
int GetNumSetting(const QString &key, int defaultval=0)
Dialog prompting the user to enter a text string.
QString GetImageFilename(void) const
bool HandleMediaEscape(MediaMonitor *)
void DoDeleteMarked(bool doDelete)
void DoMkDir(QString folderName)
void LoadThumbnail(ThumbItem *item)
bool keyPressEvent(QKeyEvent *) override
Key event handler.
#define LOG(_MASK_, _LEVEL_, _STRING_)
MythMenu * CreateMarkingMenu(void)
bool Create(void) override
ThumbGenerator * m_thumbGen
bool GetBoolSetting(const QString &key, bool defaultval=false)
void HandleDeleteMarked(void)
void InitCaption(bool get_caption)
void SetRotationAngle(int angle)
void DoRename(QString folderName)
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
void HandleRotateCCW(void)
void HandleSlideShow(void)
ChildCountThread(QObject *parent)
void ClearSettingsCache(const QString &myKey=QString(""))
bool isFinished(void) const
bool SetFocusWidget(MythUIType *widget=nullptr)
MythMediaDevice * m_currDevice
Screen in which all other widgets are contained and rendered.
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
QList< ThumbItem * > m_itemList
MythMenu * CreateMetadataMenu(void)
void SetupMediaMonitor(void)
static bool is_subdir(const QDir &parent, const QDir &subdir)
void setSize(int w, int h)
MythUIImage * m_selectedImage
bool Create(void) override
bool keyPressEvent(QKeyEvent *) override
Key event handler.
void ImportFromDir(const QString &fromDir, const QString &toDir)