bool MythWebPage::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output) { if (extension == QWebPage::ErrorPageExtension) { if (!option || !output) return false; const ErrorPageExtensionOption *erroroption = static_cast<const ErrorPageExtensionOption *>(option); ErrorPageExtensionReturn *erroroutput = NULL; erroroutput = static_cast<ErrorPageExtensionReturn *>(output); QString filename = "htmls/notfound.html"; if (!GetMythUI()->FindThemeFile(filename)) return false; QFile file(QLatin1String(qPrintable(filename))); bool isOpened = file.open(QIODevice::ReadOnly); if (!isOpened) return false; QString title = tr("Error loading page: %1").arg(erroroption->url.toString()); QString html = QString(QLatin1String(file.readAll())) .arg(title) .arg(erroroption->errorString) .arg(erroroption->url.toString()); QBuffer imageBuffer; imageBuffer.open(QBuffer::ReadWrite); QIcon icon = qApp->style()->standardIcon(QStyle::SP_MessageBoxWarning, 0, 0); QPixmap pixmap = icon.pixmap(QSize(32, 32)); if (pixmap.save(&imageBuffer, "PNG")) { html.replace(QLatin1String("IMAGE_BINARY_DATA_HERE"), QString(QLatin1String(imageBuffer.buffer().toBase64()))); } erroroutput->content = html.toUtf8(); return true; } return false; }
static int runMenu(QString which_menu) { QString themedir = GetMythUI()->GetThemeDir(); // find the 'mainmenu' MythThemedMenu so we can use the callback from it MythThemedMenu *mainMenu = NULL; QObject *parentObject = GetMythMainWindow()->GetMainStack()->GetTopScreen(); while (parentObject) { MythThemedMenu *menu = dynamic_cast<MythThemedMenu *>(parentObject); if (menu && menu->objectName() == "mainmenu") { mainMenu = menu; break; } parentObject = parentObject->parent(); } MythThemedMenu *diag = new MythThemedMenu( themedir, which_menu, GetMythMainWindow()->GetMainStack(), "music menu"); // save the callback from the main menu if (mainMenu) mainMenu->getCallback(&m_callback, &m_callbackdata); diag->setCallback(MusicCallback, NULL); diag->setKillable(); if (diag->foundTheme()) { if (LCD *lcd = LCD::Get()) { lcd->switchToTime(); } GetMythMainWindow()->GetMainStack()->AddScreen(diag); return 0; } else { LOG(VB_GENERAL, LOG_ERR, QString("Couldn't find menu %1 or theme %2") .arg(which_menu).arg(themedir)); delete diag; return -1; } }
/** \fn GalleryViewHelper::DeleteCurrentNode() * \brief Deletes the current node from the generic tree * \return void */ void GalleryViewHelper::DeleteCurrentNode() { ImageMetadata *im = GetImageMetadataFromSelectedNode(); // TODO: Remove directories as well if (im && im->m_type >= kImageFile) // Delete the file and remove the database entry if (m_fileHelper->RemoveFile(im)) { // Remove the entry from the node list m_currentNode->deleteNode(m_currentNode->getSelectedChild()); // Clean up thumbnail cache GetMythUI()->RemoveFromCacheByFile(im->m_thumbFileNameList->at(0)); } }
ZMLivePlayer::ZMLivePlayer(MythScreenStack *parent) :MythScreenType(parent, "zmliveview") { m_paused = false; m_players = NULL; m_monitors = NULL; m_monitorLayout = 1; GetMythUI()->DoDisableScreensaver(); m_frameTimer = new QTimer(this); connect(m_frameTimer, SIGNAL(timeout()), this, SLOT(updateFrame())); getMonitorList(); }
bool XMLParseBase::LoadBaseTheme(const QString &baseTheme) { VERBOSE(VB_GUI, LOC + QString("Asked to load base file from '%1'").arg(baseTheme)); if (loadedBaseFiles.contains(baseTheme)) { VERBOSE(VB_GUI, LOC + QString("Base file already loaded '%1'").arg(baseTheme)); return true; } bool ok = false; bool loadOnlyWindows = false; bool showWarnings = true; const QStringList searchpath = GetMythUI()->GetThemeSearchPath(); QStringList::const_iterator it = searchpath.begin(); for (; it != searchpath.end(); ++it) { QString themefile = *it + baseTheme; if (doLoad(QString(), GetGlobalObjectStore(), themefile, loadOnlyWindows, showWarnings)) { VERBOSE(VB_GUI, LOC + QString("Loaded base theme from '%1'").arg(themefile)); // Don't complain about duplicate definitions after first // successful load (set showWarnings to false). showWarnings = false; ok = true; } else { VERBOSE(VB_GUI|VB_FILE, LOC_WARN + QString("No theme file '%1'").arg(themefile)); } } if (ok) loadedBaseFiles.append(baseTheme); return ok; }
void ImageView::GetScreenShot(QImage& image, const ThumbItem *item) { QFileInfo fi(item->GetPath()); QString screenshot = QString("%1%2-screenshot.jpg") .arg(ThumbGenerator::getThumbcacheDir(fi.path())) .arg(item->GetName()); if (QFile::exists(screenshot)) { QImage img(screenshot); image = img; } else { QString movie("gallery-moviethumb.png"); if (GetMythUI()->FindThemeFile(movie)) image.load(movie); } }
/** \fn GalleryViewHelper::DeleteSelectedNodes() * \brief Deletes multiple selected nodes from the generic tree * \return void */ void GalleryViewHelper::DeleteSelectedNodes() { QList<MythGenericTree *> *nodeTree = m_currentNode->getAllChildren(); for (int i = 0; i < nodeTree->size(); i++) { ImageMetadata *im = nodeTree->at(i)->GetData().value<ImageMetadata *>(); // TODO: Remove directories as well if (im && im->m_selected && im->m_type >= kImageFile) { // Delete the file and remove the database entry if (m_fileHelper->RemoveFile(im)) { // Clean up thumbnail cache GetMythUI()->RemoveFromCacheByFile(im->m_thumbFileNameList->at(0)); // Remove the entry from the node list m_currentNode->deleteNode(nodeTree->at(i)); } } } }
bool MythXDisplay::Open(void) { MythXLocker locker(this); QString dispStr = GetMythUI()->GetX11Display(); const char *dispCStr = NULL; if (!dispStr.isEmpty()) dispCStr = dispStr.toAscii().constData(); m_disp = XOpenDisplay(dispCStr); if (!m_disp) return false; xdisplays[m_disp] = this; m_screen_num = DefaultScreen(m_disp); m_screen = DefaultScreenOfDisplay(m_disp); m_black = XBlackPixel(m_disp, m_screen_num); m_depth = DefaultDepthOfScreen(m_screen); m_root = DefaultRootWindow(m_disp); return true; }
void MythUIImage::FindRandomImage(void) { QDir imageDir(m_imageDirectory); if (!imageDir.exists()) { QString themeDir = GetMythUI()->GetThemeDir() + '/'; imageDir = themeDir + m_imageDirectory; } QStringList imageTypes; QList< QByteArray > exts = QImageReader::supportedImageFormats(); QList< QByteArray >::Iterator it = exts.begin(); for (; it != exts.end(); ++it) { imageTypes.append(QString("*.").append(*it)); } imageDir.setNameFilters(imageTypes); QStringList imageList = imageDir.entryList(); QString randFile; if (imageList.size()) { // try to find a different image do { randFile = QString("%1%2").arg(m_imageDirectory) .arg(imageList.takeAt(random() % imageList.size())); } while (imageList.size() > 1 && randFile == m_OrigFilename); } m_OrigFilename = m_imageProperties.filename = randFile; }
QPixmap *EditMetadataDialog::createScaledPixmap(QString filename, int width, int height, Qt::AspectRatioMode mode) { QPixmap *pixmap = NULL; if (!filename.isEmpty()) { QImage *img = GetMythUI()->LoadScaleImage(filename); if (!img) { VERBOSE(VB_IMPORTANT, QString("EditMetadataDialog: Failed to load image %1").arg(filename)); return NULL; } else { pixmap = new QPixmap(img->scaled(width, height, mode, Qt::SmoothTransformation)); delete img; } } return pixmap; }
DialogCode ProfileGroupEditor::exec(void) { DialogCode ret = kDialogCodeAccepted; redraw = true; while ((QDialog::Accepted == ret) || redraw) { redraw = false; Load(); dialog = new ConfigurationDialogWidget(GetMythMainWindow(), "ProfileGroupEditor"); connect(dialog, SIGNAL(menuButtonPressed()), this, SLOT(callDelete())); int width = 0, height = 0; float wmult = 0.0f, hmult = 0.0f; GetMythUI()->GetScreenSettings(width, wmult, height, hmult); QVBoxLayout *layout = new QVBoxLayout(dialog); layout->setMargin((int)(20 * hmult)); layout->addWidget(listbox->configWidget(NULL, dialog)); dialog->Show(); ret = dialog->exec(); dialog->deleteLater(); dialog = NULL; if (ret == QDialog::Accepted) open(listbox->getValue().toInt()); } return kDialogCodeRejected; }
static void runMusicSelection(void) { GetMythUI()->AddCurrentLocation("musicplaylists"); startDatabaseTree(); GetMythUI()->RemoveCurrentLocation(); }
static void runMusicPlayback(void) { GetMythUI()->AddCurrentLocation("playmusic"); startPlayback(); GetMythUI()->RemoveCurrentLocation(); }
int main(int argc, char **argv) { bool bShowSettings = false; MythWelcomeCommandLineParser cmdline; if (!cmdline.Parse(argc, argv)) { cmdline.PrintHelp(); return GENERIC_EXIT_INVALID_CMDLINE; } if (cmdline.toBool("showhelp")) { cmdline.PrintHelp(); return GENERIC_EXIT_OK; } if (cmdline.toBool("showversion")) { cmdline.PrintVersion(); return GENERIC_EXIT_OK; } QApplication a(argc, argv); QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHWELCOME); int retval; if ((retval = cmdline.ConfigureLogging()) != GENERIC_EXIT_OK) return retval; if (cmdline.toBool("setup")) bShowSettings = true; #ifndef _WIN32 QList<int> signallist; signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE << SIGILL; SignalHandler handler(signallist); signal(SIGHUP, SIG_IGN); #endif gContext = new MythContext(MYTH_BINARY_VERSION); if (!gContext->Init()) { LOG(VB_GENERAL, LOG_ERR, "mythwelcome: Could not initialize MythContext. Exiting."); return GENERIC_EXIT_NO_MYTHCONTEXT; } if (!MSqlQuery::testDBConnection()) { LOG(VB_GENERAL, LOG_ERR, "mythwelcome: Could not open the database. Exiting."); return -1; } LCD::SetupLCD(); if (LCD *lcd = LCD::Get()) lcd->switchToTime(); MythTranslation::load("mythfrontend"); GetMythUI()->LoadQtConfig(); MythMainWindow *mainWindow = GetMythMainWindow(); mainWindow->Init(); initKeys(); if (bShowSettings) { MythShutdownSettings settings; settings.exec(); } else { MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack(); WelcomeDialog *welcome = new WelcomeDialog(mainStack, "mythwelcome"); if (welcome->Create()) mainStack->AddScreen(welcome, false); else return -1; do { qApp->processEvents(); usleep(5000); } while (mainStack->TotalScreens() > 0); } DestroyMythMainWindow(); delete gContext; return 0; }
bool MythUIText::ParseElement( const QString &filename, QDomElement &element, bool showWarnings) { if (element.tagName() == "area") { SetArea(parseRect(element)); m_OrigDisplayRect = m_Area; } // else if (element.tagName() == "altarea") // Unused, but maybe in future? // m_AltDisplayRect = parseRect(element); else if (element.tagName() == "font") { QString fontname = getFirstText(element); MythFontProperties *fp = GetFont(fontname); if (!fp) fp = GetGlobalFontMap()->GetFont(fontname); if (fp) { MythFontProperties font = *fp; int screenHeight = GetMythMainWindow()->GetUIScreenRect().height(); font.Rescale(screenHeight); int fontStretch = GetMythUI()->GetFontStretch(); font.AdjustStretch(fontStretch); QString state = element.attribute("state",""); if (!state.isEmpty()) { m_FontStates.insert(state, font); } else { m_FontStates.insert("default", font); *m_Font = m_FontStates["default"]; } } } else if (element.tagName() == "value") { if (element.attribute("lang","").isEmpty()) { m_Message = qApp->translate("ThemeUI", parseText(element).toUtf8(), NULL, QCoreApplication::UnicodeUTF8); } #if 0 else if (element.attribute("lang","").toLower() == gCoreContext->GetLanguageAndVariant()) #else else if (element.attribute("lang","").toLower() == "en_us") #endif { m_Message = parseText(element); } #if 0 else if (element.attribute("lang","").toLower() == gCoreContext->GetLanguage()) #else else if (element.attribute("lang","").toLower() == "en") #endif { m_Message = parseText(element); } m_DefaultMessage = m_Message; SetText(m_Message); } else if (element.tagName() == "template")
MythImage *MythUIHelper::CacheImage(const QString &url, MythImage *im, bool nodisk) { if (!im) return NULL; if (!nodisk) { QString dstfile = GetMythUI()->GetThemeCacheDir() + '/' + url; LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("Saved to Cache (%1)").arg(dstfile)); // This would probably be better off somewhere else before any // Load() calls at all. QDir themedir(GetMythUI()->GetThemeCacheDir()); if (!themedir.exists()) themedir.mkdir(GetMythUI()->GetThemeCacheDir()); // Save to disk cache im->save(dstfile, "PNG"); } // delete the oldest cached images until we fall below threshold. QMutexLocker locker(d->m_cacheLock); while (d->m_cacheSize.fetchAndAddOrdered(0) + im->byteCount() >= d->m_maxCacheSize.fetchAndAddOrdered(0) && d->imageCache.size()) { QMap<QString, MythImage *>::iterator it = d->imageCache.begin(); uint oldestTime = MythDate::current().toTime_t(); QString oldestKey = it.key(); int count = 0; for (; it != d->imageCache.end(); ++it) { if (d->CacheTrack[it.key()] < oldestTime) { if ((2 == it.value()->IncrRef()) && (it.value() != im)) { oldestTime = d->CacheTrack[it.key()]; oldestKey = it.key(); count++; } it.value()->DecrRef(); } } LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("%1 images are eligible for expiry").arg(count)); if (count > 0) { LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("Cache too big (%1), removing :%2:") .arg(d->m_cacheSize.fetchAndAddOrdered(0) + im->byteCount()) .arg(oldestKey)); d->imageCache[oldestKey]->SetIsInCache(false); d->imageCache[oldestKey]->DecrRef(); d->imageCache.remove(oldestKey); d->CacheTrack.remove(oldestKey); } else { break; } } QMap<QString, MythImage *>::iterator it = d->imageCache.find(url); if (it == d->imageCache.end()) { im->IncrRef(); d->imageCache[url] = im; d->CacheTrack[url] = MythDate::current().toTime_t(); im->SetIsInCache(true); LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("NOT IN RAM CACHE, Adding, and adding to size :%1: :%2:") .arg(url).arg(im->byteCount())); } LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("MythUIHelper::CacheImage : Cache Count = :%1: size :%2:") .arg(d->imageCache.count()) .arg(d->m_cacheSize.fetchAndAddRelaxed(0))); return d->imageCache[url]; }
void MetadataImageDownload::run() { // Always handle thumbnails first, they're higher priority. ThumbnailData *thumb; while ((thumb = moreThumbs()) != NULL) { QString sFilename = getDownloadFilename(thumb->title, thumb->url); bool exists = QFile::exists(sFilename); if (!exists && !thumb->url.isEmpty()) GetMythDownloadManager()->download(thumb->url, sFilename); // inform parent we have thumbnail ready for it if (QFile::exists(sFilename) && m_parent) { VERBOSE(VB_GENERAL|VB_EXTRA, QString("Threaded Image Thumbnail Download: %1") .arg(sFilename)); thumb->url = sFilename; QCoreApplication::postEvent(m_parent, new ThumbnailDLEvent(thumb)); } else delete thumb; } MetadataLookup *lookup; while ((lookup = moreDownloads()) != NULL) { DownloadMap downloads = lookup->GetDownloads(); DownloadMap downloaded; for (DownloadMap::iterator i = downloads.begin(); i != downloads.end(); ++i) { ArtworkType type = i.key(); ArtworkInfo info = i.value(); QString filename = getDownloadFilename( type, lookup, info.url ); if (lookup->GetHost().isEmpty()) { QString path = getLocalWritePath(lookup->GetType(), type); QDir dirPath(path); if (!dirPath.exists()) if (!dirPath.mkpath(path)) { VERBOSE(VB_GENERAL, QString("Metadata Image Download: Unable to create " "path %1, aborting download.").arg(path)); continue; } QString finalfile = path + "/" + filename; QString oldurl = info.url; info.url = finalfile; if (!QFile::exists(finalfile) || lookup->GetAllowOverwrites()) { QFile dest_file(finalfile); if (dest_file.exists()) { QFileInfo fi(finalfile); GetMythUI()->RemoveFromCacheByFile(fi.fileName()); dest_file.remove(); } VERBOSE(VB_GENERAL, QString("Metadata Image Download: %1 ->%2") .arg(oldurl).arg(finalfile)); QByteArray *download = new QByteArray(); GetMythDownloadManager()->download(oldurl, download); QImage testImage; bool didLoad = testImage.loadFromData(*download); if (!didLoad) { VERBOSE(VB_IMPORTANT,QString("Tried to write %1, " "but it appears to be an HTML redirect " "(filesize %2).") .arg(oldurl).arg(download->size())); delete download; download = NULL; continue; } if (dest_file.open(QIODevice::WriteOnly)) { off_t size = dest_file.write(*download, download->size()); if (size != download->size()) { VERBOSE(VB_IMPORTANT, QString("Image Download: Error Writing Image " "to file: %1").arg(finalfile)); } else downloaded.insert(type, info); } delete download; } else downloaded.insert(type, info); } else { QString path = getStorageGroupURL(type, lookup->GetHost()); QString finalfile = path + filename; QString oldurl = info.url; info.url = finalfile; if (!RemoteFile::Exists(finalfile) || lookup->GetAllowOverwrites()) { if (RemoteFile::Exists(finalfile)) { QFileInfo fi(finalfile); GetMythUI()->RemoveFromCacheByFile(fi.fileName()); RemoteFile::DeleteFile(finalfile); } VERBOSE(VB_GENERAL, QString("Metadata Image Download: %1 -> %2") .arg(oldurl).arg(finalfile)); QByteArray *download = new QByteArray(); GetMythDownloadManager()->download(oldurl, download); QImage testImage; bool didLoad = testImage.loadFromData(*download); if (!didLoad) { VERBOSE(VB_IMPORTANT,QString("Tried to write %1, " "but it appears to be an HTML redirect " "or corrupt file (filesize %2).") .arg(oldurl).arg(download->size())); delete download; download = NULL; continue; } RemoteFile *outFile = new RemoteFile(finalfile, true); if (!outFile->isOpen()) { VERBOSE(VB_IMPORTANT, QString("Image Download: Failed to open " "remote file (%1) for write. Does " "Storage Group Exist?") .arg(finalfile)); delete outFile; outFile = NULL; } else { off_t written = outFile->Write(*download, download->size()); if (written != download->size()) { VERBOSE(VB_IMPORTANT, QString("Image Download: Error Writing Image " "to file: %1").arg(finalfile)); } else downloaded.insert(type, info); delete outFile; outFile = NULL; } delete download; } else downloaded.insert(type, info); } } lookup->SetDownloads(downloaded); QCoreApplication::postEvent(m_parent, new ImageDLEvent(lookup)); } }
void EditAlbumartDialog::customEvent(QEvent *event) { if (event->type() == DialogCompletionEvent::kEventType) { DialogCompletionEvent *dce = (DialogCompletionEvent*)(event); // make sure the user didn't ESCAPE out of the menu if (dce->GetResult() < 0) return; QString resultid = dce->GetId(); QString resulttext = dce->GetResultText(); if (resultid == "changetypemenu") { int type = dce->GetData().toInt(); if ((type >= IT_UNKNOWN) && (type < IT_LAST)) { // get selected image in list MythUIButtonListItem *item = m_coverartList->GetItemCurrent(); if (item) { item->SetText(m_albumArt->getTypeName((ImageType) type)); AlbumArtImage *image = qVariantValue<AlbumArtImage*> (item->GetData()); if (image) { AlbumArtImage oldImage = *image; image->imageType = (ImageType) type; if (image->imageType == oldImage.imageType) return; // rename any cached image to match the new type if (image->embedded) { // update the new cached image filename image->filename = QString(GetConfDir() + "/MythMusic/AlbumArt/%1-%2.jpg") .arg(m_metadata->ID()) .arg(AlbumArtImages::getTypeFilename(image->imageType)); if (image->filename != oldImage.filename && QFile::exists(oldImage.filename)) { // remove any old cached file with the same name as the new one QFile::remove(image->filename); // rename the old cached file to the new one QFile::rename(oldImage.filename, image->filename); // force the theme image cache to refresh the image GetMythUI()->RemoveFromCacheByFile(image->filename); } // change the image type in the tag if it supports it MetaIO *tagger = m_metadata->getTagger(); if (tagger && tagger->supportsEmbeddedImages()) { if (!tagger->changeImageType(m_metadata->Filename(), &oldImage, image->imageType)) LOG(VB_GENERAL, LOG_INFO, "EditAlbumartDialog: failed to change image type"); } } else { QFileInfo fi(oldImage.filename); // get the new images filename image->filename = QString(fi.absolutePath() + "/%1.jpg") .arg(AlbumArtImages::getTypeFilename(image->imageType)); if (image->filename != oldImage.filename && QFile::exists(oldImage.filename)) { // remove any old cached file with the same name as the new one QFile::remove(image->filename); // rename the old cached file to the new one QFile::rename(oldImage.filename, image->filename); // force the theme image cache to refresh the image GetMythUI()->RemoveFromCacheByFile(image->filename); } } m_albumArtChanged = true; gridItemChanged(item); } } } } else if (resultid == "asktypemenu") { int type = dce->GetData().toInt(); if ((type >= IT_UNKNOWN) && (type < IT_LAST)) copyImageToTag((ImageType) type); } else if (resultid == "optionsmenu") { if (resulttext == tr("Edit Metadata")) switchToMetadata(); else if (resulttext == tr("Rescan For Images")) rescanForImages(); else if (resulttext == tr("Search Internet For Images")) searchForAlbumImages(); else if (resulttext == tr("Change Image Type")) showTypeMenu(); else if (resulttext == tr("Copy Selected Image To Tag")) copySelectedImageToTag(); else if (resulttext == tr("Remove Selected Image From Tag")) removeSelectedImageFromTag(); else if (resulttext == tr("Copy Image To Tag")) startCopyImageToTag(); } else if (resultid == "imagelocation") { m_imageFilename = resulttext; // save directory location for next time QFileInfo fi(m_imageFilename); gCoreContext->SaveSetting("MusicLastImageLocation", fi.canonicalPath()); showTypeMenu(false); } } else if (event->type() == MythEvent::MythEventMessage) { MythEvent *me = (MythEvent *)event; QStringList tokens = me->Message().split(" ", QString::SkipEmptyParts); if (!tokens.isEmpty()) { if (tokens[0] == "BROWSER_DOWNLOAD_FINISHED") rescanForImages(); } } }
void MetadataImageDownload::run() { RunProlog(); // Always handle thumbnails first, they're higher priority. ThumbnailData *thumb; while ((thumb = moreThumbs()) != NULL) { QString sFilename = getDownloadFilename(thumb->title, thumb->url); bool exists = QFile::exists(sFilename); if (!exists && !thumb->url.isEmpty()) { if (!GetMythDownloadManager()->download(thumb->url, sFilename)) { LOG(VB_GENERAL, LOG_ERR, QString("MetadataImageDownload: failed to download thumbnail from: %1") .arg(thumb->url)); delete thumb; continue; } } // inform parent we have thumbnail ready for it if (QFile::exists(sFilename) && m_parent) { LOG(VB_GENERAL, LOG_DEBUG, QString("Threaded Image Thumbnail Download: %1") .arg(sFilename)); thumb->url = sFilename; QCoreApplication::postEvent(m_parent, new ThumbnailDLEvent(thumb)); } else delete thumb; } while (true) { m_mutex.lock(); if (m_downloadList.isEmpty()) { // no more to process, we're done m_mutex.unlock(); break; } // Ref owns the MetadataLookup object for the duration of the loop // and it will be deleted automatically when the loop completes RefCountHandler<MetadataLookup> ref = m_downloadList.takeFirstAndDecr(); m_mutex.unlock(); MetadataLookup *lookup = ref; DownloadMap downloads = lookup->GetDownloads(); DownloadMap downloaded; bool errored = false; for (DownloadMap::iterator i = downloads.begin(); i != downloads.end(); ++i) { VideoArtworkType type = i.key(); ArtworkInfo info = i.value(); QString filename = getDownloadFilename( type, lookup, info.url ); if (lookup->GetHost().isEmpty()) { QString path = getLocalWritePath(lookup->GetType(), type); QDir dirPath(path); if (!dirPath.exists()) { if (!dirPath.mkpath(path)) { LOG(VB_GENERAL, LOG_ERR, QString("Metadata Image Download: Unable to create " "path %1, aborting download.").arg(path)); errored = true; break; } } QString finalfile = path + "/" + filename; QString oldurl = info.url; info.url = finalfile; if (!QFile::exists(finalfile) || lookup->GetAllowOverwrites()) { QFile dest_file(finalfile); if (dest_file.exists()) { QFileInfo fi(finalfile); GetMythUI()->RemoveFromCacheByFile(fi.fileName()); dest_file.remove(); } LOG(VB_GENERAL, LOG_INFO, QString("Metadata Image Download: %1 ->%2") .arg(oldurl).arg(finalfile)); QByteArray download; GetMythDownloadManager()->download(oldurl, &download); QImage testImage; bool didLoad = testImage.loadFromData(download); if (!didLoad) { LOG(VB_GENERAL, LOG_ERR, QString("Tried to write %1, but it appears to be " "an HTML redirect (filesize %2).") .arg(oldurl).arg(download.size())); errored = true; break; } if (dest_file.open(QIODevice::WriteOnly)) { off_t size = dest_file.write(download, download.size()); dest_file.close(); if (size != download.size()) { // File creation failed for some reason, delete it RemoteFile::DeleteFile(finalfile); LOG(VB_GENERAL, LOG_ERR, QString("Image Download: Error Writing Image " "to file: %1").arg(finalfile)); errored = true; break; } } } } else { QString path = getStorageGroupURL(type, lookup->GetHost()); QString finalfile = path + filename; QString oldurl = info.url; info.url = finalfile; bool exists = false; bool onMaster = false; QString resolvedFN; if (gCoreContext->IsMasterBackend() && gCoreContext->IsThisHost(lookup->GetHost())) { StorageGroup sg(getStorageGroupName(type), lookup->GetHost()); resolvedFN = sg.FindFile(filename); exists = !resolvedFN.isEmpty() && QFile::exists(resolvedFN); if (!exists) { resolvedFN = getLocalStorageGroupPath(type, lookup->GetHost()) + "/" + filename; } onMaster = true; } else exists = RemoteFile::Exists(finalfile); if (!exists || lookup->GetAllowOverwrites()) { if (exists && !onMaster) { QFileInfo fi(finalfile); GetMythUI()->RemoveFromCacheByFile(fi.fileName()); RemoteFile::DeleteFile(finalfile); } else if (exists) QFile::remove(resolvedFN); LOG(VB_GENERAL, LOG_INFO, QString("Metadata Image Download: %1 -> %2") .arg(oldurl).arg(finalfile)); QByteArray download; GetMythDownloadManager()->download(oldurl, &download); QImage testImage; bool didLoad = testImage.loadFromData(download); if (!didLoad) { LOG(VB_GENERAL, LOG_ERR, QString("Tried to write %1, but it appears to be " "an HTML redirect or corrupt file " "(filesize %2).") .arg(oldurl).arg(download.size())); errored = true; break; } if (!onMaster) { RemoteFile outFile(finalfile, true); if (!outFile.isOpen()) { LOG(VB_GENERAL, LOG_ERR, QString("Image Download: Failed to open " "remote file (%1) for write. Does " "Storage Group Exist?") .arg(finalfile)); errored = true; break; } off_t written = outFile.Write(download, download.size()); if (written != download.size()) { // File creation failed for some reason, delete it RemoteFile::DeleteFile(finalfile); LOG(VB_GENERAL, LOG_ERR, QString("Image Download: Error Writing Image " "to file: %1").arg(finalfile)); errored = true; break; } } else { QFile dest_file(resolvedFN); if (dest_file.open(QIODevice::WriteOnly)) { off_t size = dest_file.write(download, download.size()); dest_file.close(); if (size != download.size()) { // File creation failed for some reason, delete it RemoteFile::DeleteFile(resolvedFN); LOG(VB_GENERAL, LOG_ERR, QString("Image Download: Error Writing Image " "to file: %1").arg(finalfile)); errored = true; break; } } } } } if (!errored) { // update future Artwork Map with what we've successfully // retrieved (either downloaded or already existing downloaded.insert(type, info); } } if (errored) { QCoreApplication::postEvent(m_parent, new ImageDLFailureEvent(lookup)); errored = false; } lookup->SetDownloads(downloaded); QCoreApplication::postEvent(m_parent, new ImageDLEvent(lookup)); } RunEpilog(); }
bool MythUIVirtualKeyboard::Create() { if (!LoadWindowFromXML("keyboard/keyboard.xml", "keyboard", this)) return false; BuildFocusList(); loadKeyDefinitions(gCoreContext->GetLanguageAndVariant()); updateKeys(true); int screenWidth, screenHeight; float xmult, ymult; GetMythUI()->GetScreenSettings(screenWidth, xmult, screenHeight, ymult); MythRect editArea = m_parentEdit->GetArea(); MythRect area = GetArea(); MythPoint newPos; //FIXME this assumes the edit is a direct child of the parent screen MythUIType *parentScreen = NULL; parentScreen = dynamic_cast<MythUIType *>(m_parentEdit->parent()); if (parentScreen) { editArea.moveTopLeft(QPoint(editArea.x() + parentScreen->GetArea().x(), editArea.y() + parentScreen->GetArea().y())); } switch (m_preferredPos) { case VK_POSABOVEEDIT: if (editArea.y() - area.height() - 5 > 0) { newPos = QPoint(editArea.x() + editArea.width() / 2 - area.width() / 2, editArea.y() - area.height() - 5); } else { newPos = QPoint(editArea.x() + editArea.width() / 2 - area.width() / 2, editArea.y() + editArea.height() + 5); } break; case VK_POSTOPDIALOG: newPos = QPoint(screenWidth / 2 - area.width() / 2, 5); break; case VK_POSBOTTOMDIALOG: newPos = QPoint(screenWidth / 2 - area.width() / 2, screenHeight - 5 - area.height()); break; case VK_POSCENTERDIALOG: newPos = QPoint(screenWidth / 2 - area.width() / 2, screenHeight / 2 - area.height() / 2); break; default: // VK_POSBELOWEDIT if (editArea.y() + editArea.height() + area.height() + 5 < screenHeight) { newPos = QPoint(editArea.x() + editArea.width() / 2 - area.width() / 2, editArea.y() + editArea.height() + 5); } else { newPos = QPoint(editArea.x() + editArea.width() / 2 - area.width() / 2, editArea.y() - area.height() - 5); } break; } // make sure the popup doesn't go off screen if (newPos.x() < 5) newPos.setX(5); if (newPos.x() + area.width() + 5 > screenWidth) newPos.setX(screenWidth - area.width() - 5); if (newPos.y() < 5) newPos.setY(5); if (newPos.y() + area.height() + 5 > screenHeight) newPos.setY(screenHeight - area.height() - 5); SetPosition(newPos); return true; }
/** * \copydoc MythUIType::ParseElement() */ bool MythUIImage::ParseElement( const QString &filename, QDomElement &element, bool showWarnings) { QWriteLocker updateLocker(&d->m_UpdateLock); if (element.tagName() == "filename") { m_imageProperties.isThemeImage = true; // This is an image distributed with the them m_OrigFilename = m_imageProperties.filename = getFirstText(element); if (m_imageProperties.filename.endsWith('/')) { m_showingRandomImage = true; m_imageDirectory = m_imageProperties.filename; FindRandomImage(); } } else if (element.tagName() == "filepattern") { m_imageProperties.isThemeImage = true; // This is an image distributed with the theme m_OrigFilename = m_imageProperties.filename = getFirstText(element); QString tmp = element.attribute("low"); if (!tmp.isEmpty()) m_LowNum = tmp.toInt(); tmp = element.attribute("high"); if (!tmp.isEmpty()) m_HighNum = tmp.toInt(); tmp = element.attribute("cycle", "start"); if (tmp == "reverse") m_animationCycle = kCycleReverse; } else if (element.tagName() == "area") { SetArea(parseRect(element)); m_imageProperties.forceSize = m_Area.size(); } else if (element.tagName() == "preserveaspect") m_imageProperties.preserveAspect = parseBool(element); else if (element.tagName() == "crop") m_imageProperties.cropRect = parseRect(element); else if (element.tagName() == "delay") { QString value = getFirstText(element); if (value.contains(",")) { QVector<int> delays; QStringList tokens = value.split(","); QStringList::iterator it = tokens.begin(); for (; it != tokens.end(); ++it) { if ((*it).isEmpty()) { if (delays.size()) delays.append(delays[delays.size()-1]); else delays.append(0); // Default 0ms delay before first image } else { delays.append((*it).toInt()); } } if (delays.size()) { m_Delay = delays[0]; SetDelays(delays); } } else { m_Delay = value.toInt(); } } else if (element.tagName() == "reflection") { m_imageProperties.isReflected = true; QString tmp = element.attribute("axis"); if (!tmp.isEmpty()) { if (tmp.toLower() == "horizontal") m_imageProperties.reflectAxis = ReflectHorizontal; else m_imageProperties.reflectAxis = ReflectVertical; } tmp = element.attribute("shear"); if (!tmp.isEmpty()) m_imageProperties.reflectShear = tmp.toInt(); tmp = element.attribute("scale"); if (!tmp.isEmpty()) m_imageProperties.reflectScale = tmp.toInt(); tmp = element.attribute("length"); if (!tmp.isEmpty()) m_imageProperties.reflectLength = tmp.toInt(); tmp = element.attribute("spacing"); if (!tmp.isEmpty()) m_imageProperties.reflectSpacing = tmp.toInt(); } else if (element.tagName() == "mask") { QString maskfile = getFirstText(element); MythImage *newMaskImage = GetPainter()->GetFormatImage(); if (newMaskImage->Load(maskfile)) { float wmult; // Width multipler float hmult; // Height multipler GetMythUI()->GetScreenSettings(wmult, hmult); if (wmult != 1.0f || hmult != 1.0f) { int width = newMaskImage->size().width() * wmult; int height = newMaskImage->size().height() * hmult; newMaskImage->Resize(QSize(width, height)); } m_imageProperties.SetMaskImage(newMaskImage); } else m_imageProperties.SetMaskImage(NULL); newMaskImage->DecrRef(); } else if (element.tagName() == "grayscale" || element.tagName() == "greyscale") { m_imageProperties.isGreyscale = parseBool(element); } else { return MythUIType::ParseElement(filename, element, showWarnings); } m_NeedLoad = true; if (m_Parent && m_Parent->IsDeferredLoading(true)) m_NeedLoad = false; return true; }
/** * \brief Load the image(s), wraps ImageLoader::LoadImage() */ bool MythUIImage::Load(bool allowLoadInBackground, bool forceStat) { d->m_UpdateLock.lockForRead(); m_Initiator = m_EnableInitiator; QString bFilename = m_imageProperties.filename; bFilename.detach(); d->m_UpdateLock.unlock(); QString filename = bFilename; if (bFilename.isEmpty()) { Clear(); SetMinArea(MythRect()); SetRedraw(); return false; } if (getenv("DISABLETHREADEDMYTHUIIMAGE")) allowLoadInBackground = false; // Don't clear the widget before we need to, otherwise it causes // unsightly flashing. We exclude animations for now since that requires a // deeper fix bool isAnimation = (m_HighNum != m_LowNum) || m_animatedImage; if (isAnimation) Clear(); QString imagelabel; int j = 0; for (int i = m_LowNum; i <= m_HighNum && !m_animatedImage; i++) { if (!m_animatedImage && m_HighNum != m_LowNum && bFilename.contains("%1")) filename = bFilename.arg(i); ImageProperties imProps = m_imageProperties; imProps.filename = filename; imagelabel = ImageLoader::GenImageLabel(imProps); // Only load in the background if allowed and the image is // not already in our mem cache int cacheMode = kCacheIgnoreDisk; if (forceStat) cacheMode |= (int)kCacheForceStat; int cacheMode2 = kCacheNormal; if (forceStat) cacheMode2 |= (int)kCacheForceStat; bool do_background_load = false; if (allowLoadInBackground) { MythImage *img = GetMythUI()->LoadCacheImage( filename, imagelabel, GetPainter(), static_cast<ImageCacheMode>(cacheMode)); if (img) img->DecrRef(); else do_background_load = true; } if (do_background_load) { SetMinArea(MythRect()); LOG(VB_GUI | VB_FILE, LOG_DEBUG, LOC + QString("Load(), spawning thread to load '%1'").arg(filename)); m_runningThreads++; ImageLoadThread *bImgThread; bImgThread = new ImageLoadThread(this, GetPainter(), imProps, bFilename, i, static_cast<ImageCacheMode>(cacheMode2)); GetMythUI()->GetImageThreadPool()->start(bImgThread, "ImageLoad"); } else { if (!isAnimation && !GetMythUI()->IsImageInCache(imagelabel)) Clear(); // Perform a blocking load LOG(VB_GUI | VB_FILE, LOG_DEBUG, LOC + QString("Load(), loading '%1' in foreground").arg(filename)); bool aborted = false; if (ImageLoader::SupportsAnimation(filename)) { AnimationFrames *myFrames; myFrames = ImageLoader::LoadAnimatedImage(GetPainter(), imProps, static_cast<ImageCacheMode>(cacheMode2), this, aborted); // TODO We might want to handle an abort here more gracefully if (aborted) LOG(VB_GUI, LOG_DEBUG, QString("Aborted loading animated" "image %1 in foreground") .arg(filename)); SetAnimationFrames(*myFrames); delete myFrames; } else { MythImage *image = NULL; image = ImageLoader::LoadImage(GetPainter(), imProps, static_cast<ImageCacheMode>(cacheMode2), this, aborted); // TODO We might want to handle an abort here more gracefully if (aborted) LOG(VB_GUI, LOG_DEBUG, QString("Aborted loading animated" "image %1 in foreground") .arg(filename)); if (image) { if (m_imageProperties.forceSize.isNull()) SetSize(image->size()); MythRect rect(GetFullArea()); rect.setSize(image->size()); SetMinArea(rect); m_ImagesLock.lock(); m_Images[j] = image; m_ImagesLock.unlock(); SetRedraw(); d->m_UpdateLock.lockForWrite(); m_LastDisplay = QTime::currentTime(); d->m_UpdateLock.unlock(); } else { Reset(); m_ImagesLock.lock(); m_Images[j] = NULL; m_ImagesLock.unlock(); } } } ++j; } return true; }
/** \brief Handle a MythTV action for the Menus. * * \param action single action to be handled * \return true if the action is not to EXEC another program */ bool MythThemedMenu::handleAction(const QString &action, const QString &password) { MythUIMenuCallbacks *cbs = GetMythUI()->GetMenuCBs(); if (((password == "SetupPinCode") && GetMythDB()->GetNumSetting("SetupPinCodeRequired", 0)) || (!password.isEmpty() && password != "SetupPinCode")) { if (!checkPinCode(password)) return true; } if (action.left(5) == "EXEC ") { QString rest = action.right(action.length() - 5); if (cbs && cbs->exec_program) cbs->exec_program(rest); return false; } else if (action.left(7) == "EXECTV ") { QString rest = action.right(action.length() - 7).trimmed(); if (cbs && cbs->exec_program_tv) cbs->exec_program_tv(rest); } else if (action.left(5) == "MENU ") { QString menu = action.right(action.length() - 5); MythScreenStack *stack = GetScreenStack(); MythThemedMenu *newmenu = new MythThemedMenu("", menu, stack, menu, false, m_state); if (newmenu->foundTheme()) stack->AddScreen(newmenu); else delete newmenu; } else if (action.left(6) == "UPMENU") { m_wantpop = true; } else if (action.left(12) == "CONFIGPLUGIN") { QString rest = action.right(action.length() - 13); if (cbs && cbs->configplugin) cbs->configplugin(rest); } else if (action.left(6) == "PLUGIN") { QString rest = action.right(action.length() - 7); if (cbs && cbs->plugin) cbs->plugin(rest); } else if (action.left(8) == "SHUTDOWN") { if (m_allocedstate) { m_wantpop = true; } } else if (action.left(5) == "EJECT") { if (cbs && cbs->eject) cbs->eject(); } else if (action.left(5) == "JUMP ") { QString rest = action.right(action.length() - 5); GetMythMainWindow()->JumpTo(rest, false); } else if (action.left(6) == "MEDIA ") { // the format is MEDIA HANDLER URL // TODO: allow spaces in the url QStringList list = action.simplified().split(' '); if (list.size() >= 3) GetMythMainWindow()->HandleMedia(list[1], list[2]); } else { m_selection = action; if (m_state->m_callback) m_state->m_callback(m_state->m_callbackdata, m_selection); else LOG(VB_GENERAL, LOG_ERR, "Unknown menu action: " + action); } return true; }
void ThumbGenerator::loadFile(QImage& image, const QFileInfo& fi) { static int sequence = 0; if (GalleryUtil::IsMovie(fi.filePath())) { bool thumbnailCreated = false; QDir tmpDir("/tmp/mythgallery"); if (!tmpDir.exists()) { if (!tmpDir.mkdir(tmpDir.absolutePath())) { LOG(VB_GENERAL, LOG_ERR, "Unable to create temp dir for movie thumbnail creation: " + tmpDir.absolutePath()); } } if (tmpDir.exists()) { QString thumbFile = QString("%1.png") .arg(++sequence,8,10,QChar('0')); QString cmd = "mythpreviewgen"; QStringList args; args << logPropagateArgs.split(" ", QString::SkipEmptyParts); args << "--infile" << '"' + fi.absoluteFilePath() + '"'; args << "--outfile" << '"' + tmpDir.filePath(thumbFile) + '"'; MythSystemLegacy ms(cmd, args, kMSRunShell); ms.SetDirectory(tmpDir.absolutePath()); ms.Run(); if (ms.Wait() == GENERIC_EXIT_OK) { QFileInfo thumb(tmpDir.filePath(thumbFile)); if (thumb.exists()) { QImage img(thumb.absoluteFilePath()); image = img; thumbnailCreated = true; } } } if (!thumbnailCreated) { QImage *img = GetMythUI()->LoadScaleImage("gallery-moviethumb.png"); if (img) { image = *img; } } } else { #ifdef EXIF_SUPPORT // Try to get thumbnail from exif data ExifData *ed = exif_data_new_from_file(fi.absoluteFilePath() .toLocal8Bit().constData()); if (ed && ed->data) { image.loadFromData(ed->data, ed->size); } if (ed) exif_data_free(ed); if (image.width() > m_width && image.height() > m_height) return; #endif #ifdef DCRAW_SUPPORT QString extension = fi.suffix(); QSet<QString> dcrawFormats = DcrawFormats::getFormats(); int rotateAngle; if (dcrawFormats.contains(extension) && (rotateAngle = DcrawHandler::loadThumbnail(&image, fi.absoluteFilePath())) != -1 && image.width() > m_width && image.height() > m_height) { if (rotateAngle != 0) { QMatrix matrix; matrix.rotate(rotateAngle); image = image.transformed(matrix); } return; } #endif image.load(fi.absoluteFilePath()); } }
void ThemeUpdateChecker::checkForUpdate(void) { if (GetMythUI()->GetCurrentLocation(false, true) != "mainmenu") return; if (RemoteFile::Exists(m_infoPackage)) { QString remoteThemeDir = gCoreContext->GenMythURL(gCoreContext->GetSetting("MasterServerIP"), 0, QString("%1/%2").arg(m_mythVersion).arg(GetMythUI()->GetThemeName()), "Temp"); QString infoXML = remoteThemeDir; infoXML.append("/themeinfo.xml"); if (RemoteFile::Exists(infoXML)) { ThemeInfo *remoteTheme = new ThemeInfo(remoteThemeDir); if (!remoteTheme) { LOG(VB_GENERAL, LOG_ERR, QString("ThemeUpdateChecker::checkForUpdate(): " "Unable to create ThemeInfo for %1") .arg(infoXML)); return; } ThemeInfo *localTheme = new ThemeInfo(GetMythUI()->GetThemeDir()); if (!localTheme) { LOG(VB_GENERAL, LOG_ERR, "ThemeUpdateChecker::checkForUpdate(): " "Unable to create ThemeInfo for current theme"); return; } int rmtMaj = remoteTheme->GetMajorVersion(); int rmtMin = remoteTheme->GetMinorVersion(); int locMaj = localTheme->GetMajorVersion(); int locMin = localTheme->GetMinorVersion(); if ((rmtMaj > locMaj) || ((rmtMaj == locMaj) && (rmtMin > locMin))) { m_lastKnownThemeVersion = QString("%1-%2.%3").arg(GetMythUI()->GetThemeName()) .arg(rmtMaj).arg(rmtMin); QString status = gCoreContext->GetSetting("ThemeUpdateStatus"); QString currentLocation = GetMythUI()->GetCurrentLocation(false, true); if ((!status.startsWith(m_lastKnownThemeVersion)) && (currentLocation == "mainmenu")) { m_currentVersion = QString("%1.%2").arg(locMaj).arg(locMin); m_newVersion = QString("%1.%2").arg(rmtMaj).arg(rmtMin); gCoreContext->SaveSetting("ThemeUpdateStatus", m_lastKnownThemeVersion + " notified"); QString message = tr("Version %1 of the %2 theme is now " "available in the Theme Chooser. The " "currently installed version is %3.") .arg(m_newVersion) .arg(GetMythUI()->GetThemeName()) .arg(m_currentVersion); ShowOkPopup(message); } } delete remoteTheme; delete localTheme; } } }
static void runMusicStreamPlayback(void) { GetMythUI()->AddCurrentLocation("streammusic"); startStreamPlayback(); GetMythUI()->RemoveCurrentLocation(); }
void MetadataImageDownload::run() { RunProlog(); // Always handle thumbnails first, they're higher priority. ThumbnailData *thumb; while ((thumb = moreThumbs()) != NULL) { QString sFilename = getDownloadFilename(thumb->title, thumb->url); bool exists = QFile::exists(sFilename); if (!exists && !thumb->url.isEmpty()) { if (!GetMythDownloadManager()->download(thumb->url, sFilename)) { LOG(VB_GENERAL, LOG_ERR, QString("MetadataImageDownload: failed to download thumbnail from: %1") .arg(thumb->url)); delete thumb; continue; } } // inform parent we have thumbnail ready for it if (QFile::exists(sFilename) && m_parent) { LOG(VB_GENERAL, LOG_DEBUG, QString("Threaded Image Thumbnail Download: %1") .arg(sFilename)); thumb->url = sFilename; QCoreApplication::postEvent(m_parent, new ThumbnailDLEvent(thumb)); } else delete thumb; } MetadataLookup *lookup; while ((lookup = moreDownloads()) != NULL) { DownloadMap downloads = lookup->GetDownloads(); DownloadMap downloaded; for (DownloadMap::iterator i = downloads.begin(); i != downloads.end(); ++i) { VideoArtworkType type = i.key(); ArtworkInfo info = i.value(); QString filename = getDownloadFilename( type, lookup, info.url ); if (lookup->GetHost().isEmpty()) { QString path = getLocalWritePath(lookup->GetType(), type); QDir dirPath(path); if (!dirPath.exists()) if (!dirPath.mkpath(path)) { LOG(VB_GENERAL, LOG_ERR, QString("Metadata Image Download: Unable to create " "path %1, aborting download.").arg(path)); QCoreApplication::postEvent(m_parent, new ImageDLFailureEvent(lookup)); continue; } QString finalfile = path + "/" + filename; QString oldurl = info.url; info.url = finalfile; if (!QFile::exists(finalfile) || lookup->GetAllowOverwrites()) { QFile dest_file(finalfile); if (dest_file.exists()) { QFileInfo fi(finalfile); GetMythUI()->RemoveFromCacheByFile(fi.fileName()); dest_file.remove(); } LOG(VB_GENERAL, LOG_INFO, QString("Metadata Image Download: %1 ->%2") .arg(oldurl).arg(finalfile)); QByteArray *download = new QByteArray(); GetMythDownloadManager()->download(oldurl, download); QImage testImage; bool didLoad = testImage.loadFromData(*download); if (!didLoad) { LOG(VB_GENERAL, LOG_ERR, QString("Tried to write %1, but it appears to be " "an HTML redirect (filesize %2).") .arg(oldurl).arg(download->size())); delete download; download = NULL; QCoreApplication::postEvent(m_parent, new ImageDLFailureEvent(lookup)); continue; } if (dest_file.open(QIODevice::WriteOnly)) { off_t size = dest_file.write(*download, download->size()); if (size != download->size()) { LOG(VB_GENERAL, LOG_ERR, QString("Image Download: Error Writing Image " "to file: %1").arg(finalfile)); QCoreApplication::postEvent(m_parent, new ImageDLFailureEvent(lookup)); } else downloaded.insert(type, info); } delete download; } else downloaded.insert(type, info); } else { QString path = getStorageGroupURL(type, lookup->GetHost()); QString finalfile = path + filename; QString oldurl = info.url; info.url = finalfile; bool exists = false; bool onMaster = false; QString resolvedFN; if ((lookup->GetHost().toLower() == gCoreContext->GetHostName().toLower()) || (gCoreContext->IsThisHost(lookup->GetHost()))) { StorageGroup sg; resolvedFN = sg.FindFile(filename); exists = QFile::exists(resolvedFN); if (!exists) { resolvedFN = getLocalStorageGroupPath(type, lookup->GetHost()) + "/" + filename; } onMaster = true; } else exists = RemoteFile::Exists(finalfile); if (!exists || lookup->GetAllowOverwrites()) { if (exists && !onMaster) { QFileInfo fi(finalfile); GetMythUI()->RemoveFromCacheByFile(fi.fileName()); RemoteFile::DeleteFile(finalfile); } else if (exists) QFile::remove(resolvedFN); LOG(VB_GENERAL, LOG_INFO, QString("Metadata Image Download: %1 -> %2") .arg(oldurl).arg(finalfile)); QByteArray *download = new QByteArray(); GetMythDownloadManager()->download(oldurl, download); QImage testImage; bool didLoad = testImage.loadFromData(*download); if (!didLoad) { LOG(VB_GENERAL, LOG_ERR, QString("Tried to write %1, but it appears to be " "an HTML redirect or corrupt file " "(filesize %2).") .arg(oldurl).arg(download->size())); delete download; download = NULL; QCoreApplication::postEvent(m_parent, new ImageDLFailureEvent(lookup)); continue; } if (!onMaster) { RemoteFile *outFile = new RemoteFile(finalfile, true); if (!outFile->isOpen()) { LOG(VB_GENERAL, LOG_ERR, QString("Image Download: Failed to open " "remote file (%1) for write. Does " "Storage Group Exist?") .arg(finalfile)); delete outFile; outFile = NULL; QCoreApplication::postEvent(m_parent, new ImageDLFailureEvent(lookup)); } else { off_t written = outFile->Write(*download, download->size()); if (written != download->size()) { LOG(VB_GENERAL, LOG_ERR, QString("Image Download: Error Writing Image " "to file: %1").arg(finalfile)); QCoreApplication::postEvent(m_parent, new ImageDLFailureEvent(lookup)); } else downloaded.insert(type, info); delete outFile; outFile = NULL; } } else { QFile dest_file(resolvedFN); if (dest_file.open(QIODevice::WriteOnly)) { off_t size = dest_file.write(*download, download->size()); if (size != download->size()) { LOG(VB_GENERAL, LOG_ERR, QString("Image Download: Error Writing Image " "to file: %1").arg(finalfile)); QCoreApplication::postEvent(m_parent, new ImageDLFailureEvent(lookup)); } else downloaded.insert(type, info); } } delete download; } else downloaded.insert(type, info); } } lookup->SetDownloads(downloaded); QCoreApplication::postEvent(m_parent, new ImageDLEvent(lookup)); } RunEpilog(); }
static MythImage *LoadImage(MythPainter *painter, // Must be a copy for thread safety ImageProperties imProps, ImageCacheMode cacheMode, // Included only to check address, could be // replaced by generating a unique value for // each MythUIImage object? const MythUIImage *parent, bool &aborted, MythImageReader *imageReader = NULL) { QString cacheKey = GenImageLabel(imProps); if (!PreLoad(cacheKey, parent)) { aborted = true; return NULL; } QString filename = imProps.filename; MythImage *image = NULL; bool bResize = false; bool bFoundInCache = false; int w = -1; int h = -1; if (!imProps.forceSize.isNull()) { if (imProps.forceSize.width() != -1) w = imProps.forceSize.width(); if (imProps.forceSize.height() != -1) h = imProps.forceSize.height(); bResize = true; } if (!imageReader) { image = GetMythUI()->LoadCacheImage(filename, cacheKey, painter, cacheMode); } if (image) { if (VERBOSE_LEVEL_CHECK(VB_GUI | VB_FILE, LOG_INFO)) { image->IncrRef(); int cnt = image->DecrRef(); LOG(VB_GUI | VB_FILE, LOG_INFO, QString("ImageLoader::LoadImage(%1) Found in cache, " "RefCount = %2") .arg(cacheKey).arg(cnt)); } if (imProps.isReflected) image->setIsReflected(true); if (imProps.isOriented) image->setIsOriented(true); bFoundInCache = true; } else { LOG(VB_GUI | VB_FILE, LOG_INFO, QString("ImageLoader::LoadImage(%1) NOT Found in cache. " "Loading Directly").arg(cacheKey)); image = painter->GetFormatImage(); bool ok = false; if (imageReader) ok = image->Load(imageReader); else ok = image->Load(filename); if (!ok) { image->DecrRef(); image = NULL; } } if (image && image->isNull()) { LOG(VB_GUI | VB_FILE, LOG_INFO, QString("ImageLoader::LoadImage(%1) Image is NULL") .arg(filename)); image->DecrRef(); image = NULL; } if (image && !bFoundInCache) { if (imProps.isReflected) image->Reflect(imProps.reflectAxis, imProps.reflectShear, imProps.reflectScale, imProps.reflectLength, imProps.reflectSpacing); if (imProps.isGreyscale) image->ToGreyscale(); if (imProps.isOriented) image->Orientation(imProps.orientation); // Even if an explicit size wasn't defined this image may still need // to be scaled because of a difference between the theme resolution // and the screen resolution. We want to avoid scaling twice. if (!bResize && imProps.isThemeImage) { float wmult; // Width multipler float hmult; // Height multipler GetMythUI()->GetScreenSettings(wmult, hmult); if (wmult != 1.0f || hmult != 1.0f) { w = image->size().width() * wmult; h = image->size().height() * hmult; bResize = true; } } if (bResize) image->Resize(QSize(w, h), imProps.preserveAspect); if (imProps.isMasked) { QRect imageArea = image->rect(); QRect maskArea = imProps.GetMaskImageRect(); // Crop the mask to the image int x = 0; int y = 0; if (maskArea.width() > imageArea.width()) x = (maskArea.width() - imageArea.width()) / 2; if (maskArea.height() > imageArea.height()) y = (maskArea.height() - imageArea.height()) / 2; if (x > 0 || y > 0) imageArea.translate(x, y); QImage mask = imProps.GetMaskImageSubset(imageArea); image->setAlphaChannel(mask.alphaChannel()); } if (!imageReader) GetMythUI()->CacheImage(cacheKey, image); } if (image) image->SetChanged(); PostLoad(cacheKey); return image; }
void GameHandler::Launchgame(RomInfo *romdata, QString systemname) { GameHandler *handler; if (!systemname.isEmpty() && !systemname.isNull()) { handler = GetHandlerByName(systemname); } else if (!(handler = GetHandler(romdata))) { // Couldn't get handler so abort. return; } QString exec = handler->SystemCmdLine(); if (exec.isEmpty()) return; if (handler->GameType() != "PC") { QString arg = "\"" + romdata->Rompath() + "/" + romdata->Romname() + "\""; // If they specified a %s in the commandline place the romname // in that location, otherwise tack it on to the end of // the command. if (exec.contains("%s") || handler->SpanDisks()) { exec = exec.replace(QRegExp("%s"),arg); if (handler->SpanDisks()) { QRegExp rxp = QRegExp( "%d[0-4]", Qt::CaseSensitive, QRegExp::RegExp); if (exec.contains(rxp)) { if (romdata->DiskCount() > 1) { // Chop off the extension, . and last character of the name which we are assuming is the disk # QString basename = romdata->Romname().left(romdata->Romname().length() - (romdata->getExtension().length() + 2)); QString extension = romdata->getExtension(); QString rom; QString diskid[] = { "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6" }; for (int disk = 1; disk <= romdata->DiskCount(); disk++) { rom = QString("\"%1/%2%3.%4\"") .arg(romdata->Rompath()) .arg(basename) .arg(disk) .arg(extension); exec = exec.replace(QRegExp(diskid[disk]),rom); } } else { // If there is only one disk make sure we replace %d1 just like %s exec = exec.replace(QRegExp("%d1"),arg); } } } } else { exec = exec + " \"" + romdata->Rompath() + "/" + romdata->Romname() + "\""; } } QString savedir = QDir::current().path(); QDir d; if (!handler->SystemWorkingPath().isEmpty()) { if (!d.cd(handler->SystemWorkingPath())) { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to change to specified Working Directory: %1") .arg(handler->SystemWorkingPath())); } } LOG(VB_GENERAL, LOG_INFO, LOC + QString("Launching Game : %1 : %2") .arg(handler->SystemName()) .arg(exec)); GetMythUI()->AddCurrentLocation(QString("MythGame %1 ( %2 )").arg(handler->SystemName()).arg(exec)); QStringList cmdlist = exec.split(";"); if (cmdlist.count() > 0) { for (QStringList::Iterator cmd = cmdlist.begin(); cmd != cmdlist.end(); ++cmd ) { LOG(VB_GENERAL, LOG_INFO, LOC + QString("Executing : %1").arg(*cmd)); myth_system(*cmd, kMSProcessEvents); } } else { LOG(VB_GENERAL, LOG_INFO, LOC + QString("Executing : %1").arg(exec)); myth_system(exec, kMSProcessEvents); } GetMythUI()->RemoveCurrentLocation(); (void)d.cd(savedir); }
void MythFontProperties::SetPixelSize(float size) { QSize baseSize = GetMythUI()->GetBaseSize(); m_relativeSize = size / (float)(baseSize.height()); m_face.setPixelSize(GetMythMainWindow()->NormY((int)(size + 0.5f))); }