Ticket #603: gallery_removable_v3.patch
File gallery_removable_v3.patch, 37.0 KB (added by , 18 years ago) |
---|
-
mythplugins/mythgallery/mythgallery/galleryutil.h
1 // -*- Mode: c++ -*- 1 2 /* ============================================================ 2 3 * File : exifutil.h 3 4 * Description : … … 23 24 24 25 class GalleryUtil 25 26 { 26 27 public: 27 public: 28 28 static bool isImage(const char* filePath); 29 29 static bool isMovie(const char* filePath); 30 30 static long getNaturalRotation(const char* filePath); … … 34 34 static bool loadDirectory(ThumbList& itemList, 35 35 const QString& dir, bool recurse, 36 36 ThumbDict *itemDict, ThumbGenerator* thumbGen); 37 38 static bool CopyMove(const QFileInfo &src, QFileInfo &dst, bool move) 39 { if (move) return Move(src, dst); else return Copy(src, dst); } 40 41 static bool Copy(const QFileInfo &src, QFileInfo &dst); 42 static bool Move(const QFileInfo &src, QFileInfo &dst); 43 static bool Delete(const QFileInfo &file); 44 45 private: 46 static bool CopyDirectory(const QFileInfo src, QFileInfo &dst); 47 static bool MoveDirectory(const QFileInfo src, QFileInfo &dst); 48 static bool DeleteDirectory(const QFileInfo &dir); 37 49 }; 38 50 39 51 #endif /* EXIFUTIL_H */ -
mythplugins/mythgallery/mythgallery/iconview.cpp
31 31 #include <mythtv/xmlparse.h> 32 32 #include <mythtv/dialogbox.h> 33 33 #include <mythtv/mythdbcon.h> 34 #include <mythtv/mythmediamonitor.h> 35 #include <mythtv/mythdialogs.h> 34 36 35 37 #include "galleryutil.h" 36 38 #include "gallerysettings.h" … … 84 86 return false; 85 87 } 86 88 87 IconView::IconView(const QString& galleryDir, MythM ainWindow* parent,88 const char* name )89 IconView::IconView(const QString& galleryDir, MythMediaDevice *initialDevice, 90 MythMainWindow* parent, const char* name ) 89 91 : MythDialog(parent, name) 90 92 { 91 93 m_galleryDir = galleryDir; 92 94 93 95 m_inMenu = false; 96 m_inSubMenu = false; 94 97 m_itemList.setAutoDelete(true); 95 98 m_itemDict.setAutoDelete(false); 96 99 … … 108 111 m_lastCol = 0; 109 112 m_topRow = 0; 110 113 m_isGallery = false; 114 #ifndef _WIN32 115 m_showDevices = false; 116 m_currDevice = initialDevice; 117 #endif 111 118 112 119 srand(time(NULL)); 113 loadDirectory(galleryDir); 120 121 #ifndef _WIN32 122 if (m_currDevice) 123 { 124 if (!m_currDevice->isMounted(true)) 125 m_currDevice->mount(); 126 127 connect(m_currDevice, SIGNAL(statusChanged(MediaStatus, MythMediaDevice*)), 128 SLOT(mediaStatusChanged(MediaStatus, MythMediaDevice*))); 129 130 loadDirectory(m_currDevice->getMountPath()); 131 } 132 else 133 #endif 134 loadDirectory(galleryDir); 114 135 } 115 136 116 137 IconView::~IconView() 117 138 { 118 UIListBtnTypeItem* item = m_menuType->GetItemFirst(); 119 while (item) { 120 Action *act = (Action*) item->getData(); 121 if (act) 122 delete act; 123 item = m_menuType->GetItemNext(item); 124 } 125 139 clearMenu(m_submenuType); 140 clearMenu(m_menuType); 141 126 142 delete m_thumbGen; 127 143 delete m_theme; 128 144 } … … 258 274 item->pixmap->height()/2-bh2+sh, 259 275 bw-2*sw, bh-2*sh-(int)(15*hmult)); 260 276 277 if (m_itemMarked.contains(item->path)) 278 p.drawPixmap(xpos, ypos, m_MrkPix); 279 261 280 } 262 281 else { 263 282 … … 272 291 item->pixmap->width()/2-bw2+sw, 273 292 item->pixmap->height()/2-bh2+sh, 274 293 bw-2*sw, bh-2*sh); 294 295 if (m_itemMarked.contains(item->path)) 296 p.drawPixmap(xpos, ypos, m_MrkPix); 275 297 } 276 298 277 299 curPos++; … … 299 321 QString action = actions[i]; 300 322 if (action == "MENU") { 301 323 m_inMenu = !m_inMenu; 302 m_menuType->SetActive(m_inMenu); 324 m_menuType->SetActive(m_inMenu & !m_inSubMenu); 325 m_submenuType->SetActive(m_inMenu & m_inSubMenu); 303 326 menuHandled = true; 304 327 } 305 328 else if (action == "UP") { 306 if (m_inMenu ) {329 if (m_inMenu & !m_inSubMenu) { 307 330 m_menuType->MoveUp(); 308 331 menuHandled = true; 309 332 } 333 else if (m_inMenu & m_inSubMenu) { 334 m_submenuType->MoveUp(); 335 menuHandled = true; 336 } 310 337 else 311 338 handled = moveUp(); 312 339 } 313 340 else if (action == "DOWN") { 314 if (m_inMenu ) {341 if (m_inMenu & !m_inSubMenu) { 315 342 m_menuType->MoveDown(); 316 343 menuHandled = true; 317 344 } 345 else if (m_inMenu & m_inSubMenu) { 346 m_submenuType->MoveDown(); 347 menuHandled = true; 348 } 318 349 else 319 350 handled = moveDown(); 320 351 } … … 363 394 actionDelete(); 364 395 handled = true; 365 396 } 397 else if (action == "MARK") 398 { 399 int pos = m_currRow * m_nCols + m_currCol; 400 ThumbItem *item = m_itemList.at(pos); 401 if (!item) { 402 std::cerr << "The impossible happened" << std::endl; 403 break; 404 } 405 406 std::cout << "(un)marking " << item->path.ascii() << std::endl; 407 408 if (!m_itemMarked.contains(item->path)) 409 m_itemMarked.append(item->path); 410 else 411 m_itemMarked.remove(item->path); 412 413 handled = true; 414 } 366 415 else if (action == "SELECT" || action == "PLAY" || action == "SLIDESHOW" || action == "RANDOMSHOW" ) 367 416 { 368 417 if (m_inMenu && (action == "SELECT" || action == "PLAY") ) { … … 378 427 } 379 428 380 429 QFileInfo fi(item->path); 430 #ifndef _WIN32 431 // if the selected item is a mediaDevice attempt to mount it if it isn't already 432 if (item->mediaDevice && (action == "SELECT" || action == "PLAY") ) 433 { 434 m_currDevice = item->mediaDevice; 435 436 if (!m_currDevice->isMounted()) 437 m_currDevice->mount(); 438 439 item->path = m_currDevice->getMountPath(); 440 441 connect(m_currDevice, SIGNAL(statusChanged(MediaStatus, MythMediaDevice*)), 442 SLOT(mediaStatusChanged(MediaStatus, MythMediaDevice*))); 443 } 444 #endif 381 445 if (item->isDir && (action == "SELECT" || action == "PLAY") ) { 382 446 loadDirectory(item->path); 383 447 handled = true; … … 426 490 { 427 491 QString action = actions[i]; 428 492 if (action == "ESCAPE") { 429 QDir d(m_currDir); 430 if (d != QDir(m_galleryDir)) { 493 #ifndef _WIN32 494 if (m_showDevices) 495 { 496 loadDirectory(m_galleryDir); 497 handled = true; 498 } 499 else 500 { 501 #endif 502 QDir d(m_currDir); 503 #ifndef _WIN32 504 MediaMonitor *mon = MediaMonitor::GetMediaMonitor(); 505 if (mon) 506 { 507 QValueList <MythMediaDevice *> removables = 508 mon->GetMedias(MEDIATYPE_DATA); 509 QValueList <MythMediaDevice *>::Iterator it = removables.begin(); 510 for (; it != removables.end(); it++) 511 { 512 if (d == QDir((*it)->getMountPath())) 513 { 514 actionShowDevices(); 431 515 432 QString oldDirName = d.dirName(); 433 d.cdUp(); 434 loadDirectory(d.absPath()); 516 // make sure previous devies is visible and selected 517 ThumbItem *item; 518 if ((*it)->getVolumeID() != "") 519 item = m_itemDict.find((*it)->getVolumeID()); 520 else 521 item = m_itemDict.find((*it)->getDevicePath()); 435 522 436 // make sure up-directory is visible and selected 437 ThumbItem* item = m_itemDict.find(oldDirName); 438 if (item) { 439 int pos = m_itemList.find(item); 440 if (pos != -1) { 441 m_currRow = pos/m_nCols; 442 m_currCol = pos-m_currRow*m_nCols; 443 m_topRow = QMAX(0, m_currRow-(m_nRows-1)); 523 if (item) 524 { 525 int pos = m_itemList.find(item); 526 if (pos != -1) 527 { 528 m_currRow = pos/m_nCols; 529 m_currCol = pos-m_currRow*m_nCols; 530 m_topRow = QMAX(0, m_currRow-(m_nRows-1)); 531 } 532 } 533 handled = true; 534 break; 535 } 444 536 } 445 537 } 446 handled = true; 538 if (!handled) 539 { 540 #endif 541 if (d != QDir(m_galleryDir)) { 542 543 QString oldDirName = d.dirName(); 544 d.cdUp(); 545 loadDirectory(d.absPath()); 546 547 // make sure up-directory is visible and selected 548 ThumbItem* item = m_itemDict.find(oldDirName); 549 if (item) { 550 int pos = m_itemList.find(item); 551 if (pos != -1) { 552 m_currRow = pos/m_nCols; 553 m_currCol = pos-m_currRow*m_nCols; 554 m_topRow = QMAX(0, m_currRow-(m_nRows-1)); 555 } 556 } 557 handled = true; 558 } 559 #ifndef _WIN32 560 } 447 561 } 562 #endif 448 563 } 449 564 } 450 565 } … … 547 662 exit(-1); 548 663 } 549 664 665 m_submenuType = (UIListBtnType*)container->GetType("submenu"); 666 if (!m_menuType) { 667 std::cerr << "MythGallery: Failed to get submenu area." 668 << std::endl; 669 exit(-1); 670 } 671 550 672 // Menu Actions 551 673 552 674 UIListBtnTypeItem* item; … … 554 676 item->setData(new Action(&IconView::actionSlideShow)); 555 677 item = new UIListBtnTypeItem(m_menuType, tr("Random")); 556 678 item->setData(new Action(&IconView::actionRandomShow)); 557 item = new UIListBtnTypeItem(m_menuType, tr("Rotate CW")); 558 item->setData(new Action(&IconView::actionRotateCW)); 559 item = new UIListBtnTypeItem(m_menuType, tr("Rotate CCW")); 560 item->setData(new Action(&IconView::actionRotateCCW)); 679 item = new UIListBtnTypeItem(m_menuType, tr("Meta Data...")); 680 item->setData(new Action(&IconView::actionSubMenuMetadata)); 681 item = new UIListBtnTypeItem(m_menuType, tr("Marking...")); 682 item->setData(new Action(&IconView::actionSubMenuMark)); 683 item = new UIListBtnTypeItem(m_menuType, tr("File...")); 684 item->setData(new Action(&IconView::actionSubMenuFile)); 561 685 item = new UIListBtnTypeItem(m_menuType, tr("Delete")); 562 686 item->setData(new Action(&IconView::actionDelete)); 563 item = new UIListBtnTypeItem(m_menuType, tr("Import"));564 item->setData(new Action(&IconView::actionImport));565 687 item = new UIListBtnTypeItem(m_menuType, tr("Settings")); 566 688 item->setData(new Action(&IconView::actionSettings)); 567 689 … … 618 740 m_folderSelPix = QPixmap(*img); 619 741 delete img; 620 742 743 img = gContext->LoadScaleImage("gallery-mark.png"); 744 if (!img) { 745 std::cerr << "Failed to load gallery-mark.png" 746 << std::endl; 747 exit(-1); 748 } 749 m_MrkPix = QPixmap(*img); 750 delete img; 751 621 752 m_thumbW = m_backRegPix.width(); 622 753 m_thumbH = m_backRegPix.height(); 623 754 m_nCols = m_viewRect.width()/m_thumbW - 1; … … 634 765 if (!d.exists()) 635 766 return; 636 767 768 #ifndef _WIN32 769 m_showDevices = false; 770 #endif 771 637 772 m_currDir = d.absPath(); 638 773 m_itemList.clear(); 639 774 m_itemDict.clear(); … … 778 913 779 914 void IconView::pressMenu() 780 915 { 781 UIListBtnTypeItem* item = m_menuType->GetItemCurrent();916 UIListBtnTypeItem* item; 782 917 918 if (m_inSubMenu) 919 item = m_submenuType->GetItemCurrent(); 920 else 921 item = m_menuType->GetItemCurrent(); 922 783 923 if (!item || !item->getData()) 784 924 return; 785 925 786 926 Action *act = (Action*) item->getData(); 787 927 (this->*(*act))(); 928 929 m_menuType->SetActive(m_inMenu & !m_inSubMenu); 930 m_submenuType->SetActive(m_inMenu & m_inSubMenu); 788 931 } 789 932 933 void IconView::actionMainMenu() 934 { 935 clearMenu(m_submenuType); 936 m_submenuType->Reset(); 937 938 m_inSubMenu = false; 939 } 940 941 void IconView::actionSubMenuMetadata() 942 { 943 clearMenu(m_submenuType); 944 m_submenuType->Reset(); 945 946 UIListBtnTypeItem *item; 947 item = new UIListBtnTypeItem(m_submenuType, tr("Return")); 948 item->setData(new Action(&IconView::actionMainMenu)); 949 item = new UIListBtnTypeItem(m_submenuType, tr("Rotate CW")); 950 item->setData(new Action(&IconView::actionRotateCW)); 951 item = new UIListBtnTypeItem(m_submenuType, tr("Rotate CCW")); 952 item->setData(new Action(&IconView::actionRotateCCW)); 953 954 m_inSubMenu = true; 955 } 956 957 void IconView::actionSubMenuMark() 958 { 959 clearMenu(m_submenuType); 960 m_submenuType->Reset(); 961 962 UIListBtnTypeItem *item; 963 item = new UIListBtnTypeItem(m_submenuType, tr("Return")); 964 item->setData(new Action(&IconView::actionMainMenu)); 965 item = new UIListBtnTypeItem(m_submenuType, tr("Clear Marked")); 966 item->setData(new Action(&IconView::actionClearMarked)); 967 item = new UIListBtnTypeItem(m_submenuType, tr("Select All")); 968 item->setData(new Action(&IconView::actionSelectAll)); 969 970 m_inSubMenu = true; 971 } 972 973 void IconView::actionSubMenuFile() 974 { 975 clearMenu(m_submenuType); 976 m_submenuType->Reset(); 977 978 UIListBtnTypeItem *item; 979 item = new UIListBtnTypeItem(m_submenuType, tr("Return")); 980 item->setData(new Action(&IconView::actionMainMenu)); 981 #ifndef _WIN32 982 item = new UIListBtnTypeItem(m_submenuType, tr("Show Devices")); 983 item->setData(new Action(&IconView::actionShowDevices)); 984 #endif 985 item = new UIListBtnTypeItem(m_submenuType, tr("Import")); 986 item->setData(new Action(&IconView::actionImport)); 987 item = new UIListBtnTypeItem(m_submenuType, tr("Copy here")); 988 item->setData(new Action(&IconView::actionCopyHere)); 989 item = new UIListBtnTypeItem(m_submenuType, tr("Move here")); 990 item->setData(new Action(&IconView::actionMoveHere)); 991 item = new UIListBtnTypeItem(m_submenuType, tr("Delete Marked")); 992 item->setData(new Action(&IconView::actionDeleteMarked)); 993 item = new UIListBtnTypeItem(m_submenuType, tr("Create Dir")); 994 item->setData(new Action(&IconView::actionMkDir)); 995 996 m_inSubMenu = true; 997 } 998 790 999 void IconView::actionRotateCW() 791 1000 { 792 1001 ThumbItem* item = m_itemList.at(m_currRow * m_nCols + … … 980 1189 } 981 1190 } 982 1191 1192 #ifndef _WIN32 1193 void IconView::actionShowDevices() 1194 { 1195 if (m_currDevice) 1196 { 1197 m_currDevice->disconnect(this); 1198 m_currDevice = NULL; 1199 } 1200 1201 m_showDevices = true; 1202 1203 m_itemList.clear(); 1204 m_itemDict.clear(); 1205 1206 m_thumbGen->cancel(); 1207 1208 /* add gallery directory */ 1209 ThumbItem *item = new ThumbItem; 1210 item->name = QString("Gallery"); 1211 item->path = m_galleryDir; 1212 item->isDir = true; 1213 m_itemList.append(item); 1214 m_itemDict.insert(item->name, item); 1215 1216 MediaMonitor *mon = MediaMonitor::GetMediaMonitor(); 1217 if (mon) 1218 { 1219 QValueList <MythMediaDevice *> removables = 1220 mon->GetMedias(MEDIATYPE_DATA); 1221 QValueList <MythMediaDevice *>::Iterator it = removables.begin(); 1222 for (; it != removables.end(); it++) 1223 { 1224 item = new ThumbItem; 1225 if ((*it)->getVolumeID() != "") 1226 item->name = (*it)->getVolumeID(); 1227 else 1228 item->name = (*it)->getDevicePath(); 1229 item->path = (*it)->getMountPath(); 1230 item->isDir = true; 1231 item->mediaDevice = *it; 1232 m_itemList.append(item); 1233 m_itemDict.insert(item->name, item); 1234 } 1235 } 1236 1237 m_lastRow = QMAX((int)ceilf((float)m_itemList.count()/(float)m_nCols)-1,0); 1238 m_lastCol = QMAX(m_itemList.count()-m_lastRow*m_nCols-1,0); 1239 } 1240 #endif 1241 1242 void IconView::actionCopyHere() 1243 { 1244 CopyMarkedFiles(false); 1245 } 1246 1247 void IconView::actionMoveHere() 1248 { 1249 CopyMarkedFiles(true); 1250 } 1251 1252 void IconView::actionDeleteMarked() 1253 { 1254 std::cerr << "deleting marked files\n"; 1255 1256 bool cont = MythPopupBox::showOkCancelPopup(gContext->GetMainWindow(), tr("Delete Marked Files"), 1257 QString(tr("Deleting %1 images and folders")) 1258 .arg(m_itemMarked.count()), false); 1259 1260 if (cont) 1261 { 1262 QStringList::iterator it; 1263 QFileInfo fi; 1264 1265 for (it = m_itemMarked.begin(); it != m_itemMarked.end(); it++) 1266 { 1267 fi.setFile(*it); 1268 1269 std::cerr << "fi = " << fi.absFilePath() << endl; 1270 1271 GalleryUtil::Delete(fi); 1272 } 1273 1274 m_itemMarked.clear(); 1275 1276 loadDirectory(m_currDir); 1277 } 1278 } 1279 1280 void IconView::actionClearMarked() 1281 { 1282 m_itemMarked.clear(); 1283 } 1284 1285 void IconView::actionSelectAll() 1286 { 1287 ThumbItem *item; 1288 for (item = m_itemList.first(); item; item = m_itemList.next()) 1289 { 1290 if (!m_itemMarked.contains(item->path)) 1291 m_itemMarked.append(item->path); 1292 } 1293 } 1294 1295 void IconView::actionMkDir() 1296 { 1297 QString folderName = tr("New Folder"); 1298 1299 bool res = MythPopupBox::showGetTextPopup(gContext->GetMainWindow(), tr("Create New Folder"), 1300 tr("Create New Folder"), folderName); 1301 1302 if (res) 1303 { 1304 QDir cdir(m_currDir); 1305 cdir.mkdir(folderName); 1306 1307 loadDirectory(m_currDir); 1308 } 1309 } 1310 983 1311 void IconView::importFromDir(const QString &fromDir, const QString &toDir) 984 1312 { 985 1313 QDir d(fromDir); … … 1019 1347 } 1020 1348 } 1021 1349 } 1350 1351 void IconView::CopyMarkedFiles(bool move) 1352 { 1353 QStringList::iterator it; 1354 QFileInfo fi; 1355 QFileInfo dest; 1356 1357 for (it = m_itemMarked.begin(); it != m_itemMarked.end(); it++) 1358 { 1359 fi.setFile(*it); 1360 dest.setFile(QDir(m_currDir), fi.fileName()); 1361 1362 if (fi.exists()) 1363 { 1364 GalleryUtil::CopyMove(fi, dest, move); 1365 *it = dest.absFilePath(); 1366 } 1367 } 1368 1369 loadDirectory(m_currDir); 1370 } 1371 1372 void IconView::clearMenu(UIListBtnType *menu) 1373 { 1374 UIListBtnTypeItem* item = menu->GetItemFirst(); 1375 while (item) 1376 { 1377 Action *act = (Action*) item->getData(); 1378 if (act) 1379 delete act; 1380 item = menu->GetItemNext(item); 1381 } 1382 } 1383 1384 void IconView::mediaStatusChanged(MediaStatus oldStatus, 1385 MythMediaDevice *pMedia) 1386 { 1387 (void) oldStatus; 1388 if (m_currDevice == pMedia) 1389 { 1390 actionShowDevices(); 1391 1392 m_currRow = 0; 1393 m_currCol = 0; 1394 1395 updateView(); 1396 updateText(); 1397 } 1398 } -
mythplugins/mythgallery/mythgallery/main.cpp
Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: mythplugins/mythgallery/mythgallery/images/gallery-mark.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream
14 14 #include <mythtv/mythdialogs.h> 15 15 #include <mythtv/mythplugin.h> 16 16 #include <mythtv/dialogbox.h> 17 #include <mythtv/mythmedia.h> 17 18 18 19 extern "C" { 19 20 int mythplugin_init(const char *libversion); … … 33 34 diag.AddButton(QObject::tr("Ok")); 34 35 diag.exec(); 35 36 } 36 else { 37 IconView icv(startdir, gContext->GetMainWindow(), "IconView"); 37 else 38 { 39 IconView icv(startdir, NULL, gContext->GetMainWindow(), "IconView"); 38 40 icv.exec(); 39 41 } 40 42 gContext->removeCurrentLocation(); 41 43 } 44 45 void handleMedia(MythMediaDevice *dev) 46 { 47 QString galleryDir = gContext->GetSetting("GalleryDir"); 48 QDir dir(galleryDir); 49 if (!dir.exists() || !dir.isReadable()) 50 { 51 DialogBox diag(gContext->GetMainWindow(), 52 QObject::tr("Gallery Directory does not " 53 "exist or is unreadable.")); 54 diag.AddButton(QObject::tr("Ok")); 55 diag.exec(); 56 } 57 else 58 { 59 IconView icv(galleryDir, dev, gContext->GetMainWindow(), "IconView"); 60 icv.exec(); 61 } 62 } 42 63 64 43 65 void setupKeys(void) 44 66 { 45 67 REG_JUMP("MythGallery", "Image viewer / slideshow", "", runGallery); … … 68 90 "PgDown"); 69 91 REG_KEY("Gallery", "INFO", "Toggle Showing Information about Image", "I"); 70 92 REG_KEY("Gallery", "DELETE", "Delete current image", "D"); 93 REG_KEY("Gallery", "MARK", "Mark image", "T"); 94 95 REG_MEDIA_HANDLER("MythGallery Media Handler", "", "", handleMedia, MEDIATYPE_DATA | MEDIATYPE_MIXED); 71 96 } 72 97 73 98 int mythplugin_init(const char *libversion) -
mythplugins/mythgallery/mythgallery/thumbgenerator.cpp
308 308 309 309 QString ThumbGenerator::getThumbcacheDir(const QString& inDir) 310 310 { 311 QString galleryDir = gContext->GetSetting("GalleryDir"); 312 311 313 // For directory "/my/images/january", this function either returns 312 314 // "/my/images/january/.thumbcache" or "~/.mythtv/mythgallery/january/.thumbcache" 313 315 QString aPath = inDir + QString("/.thumbcache/"); 314 316 if ( gContext->GetNumSetting("GalleryThumbnailLocation") 315 && ! QDir(aPath).exists() )317 && ! QDir(aPath).exists() && inDir.startsWith(galleryDir)) 316 318 { 317 319 mkpath(aPath); 318 320 } 319 if ( ! gContext->GetNumSetting("GalleryThumbnailLocation") || ! QDir(aPath).exists() )321 if ( ! gContext->GetNumSetting("GalleryThumbnailLocation") || ! QDir(aPath).exists() || ! inDir.startsWith(galleryDir)) 320 322 { 321 323 // Arrive here if storing thumbs in home dir, 322 324 // OR failed to create thumb dir in gallery pics location -
mythplugins/mythgallery/mythgallery/iconview.h
26 26 #include <qpixmap.h> 27 27 28 28 #include <mythtv/mythdialogs.h> 29 #include <mythtv/mythmedia.h> 29 30 30 31 class XMLParse; 31 32 class UIListBtnType; … … 42 43 caption= ""; 43 44 path = ""; 44 45 isDir = false; 46 mediaDevice = NULL; 45 47 } 46 48 47 49 ~ThumbItem() { … … 58 60 QString caption; 59 61 QString path; 60 62 bool isDir; 63 MythMediaDevice *mediaDevice; 61 64 }; 62 65 63 66 typedef QPtrList<ThumbItem> ThumbList; … … 69 72 70 73 public: 71 74 72 IconView(const QString& galleryDir, MythM ainWindow* parent,73 const char* name = 0);75 IconView(const QString& galleryDir, MythMediaDevice *initialDevice, 76 MythMainWindow* parent, const char* name = 0); 74 77 ~IconView(); 75 78 76 79 protected: … … 93 96 bool moveLeft(); 94 97 bool moveRight(); 95 98 99 void actionMainMenu(); 100 void actionSubMenuMetadata(); 101 void actionSubMenuMark(); 102 void actionSubMenuFile(); 103 96 104 void actionRotateCW(); 97 105 void actionRotateCCW(); 98 106 void actionDelete(); … … 100 108 void actionRandomShow(); 101 109 void actionSettings(); 102 110 void actionImport(); 111 #ifndef _WIN32 112 void actionShowDevices(); 113 #endif 114 void actionCopyHere(); 115 void actionMoveHere(); 116 void actionDeleteMarked(); 117 void actionClearMarked(); 118 void actionSelectAll(); 119 void actionMkDir(); 103 120 121 104 122 void pressMenu(); 105 123 106 124 void loadThumbnail(ThumbItem *item); 107 125 void importFromDir(const QString &fromDir, const QString &toDir); 126 void CopyMarkedFiles(bool move = false); 127 128 void clearMenu(UIListBtnType *menu); 108 129 109 130 QPtrList<ThumbItem> m_itemList; 110 131 QDict<ThumbItem> m_itemDict; 132 QStringList m_itemMarked; 111 133 QString m_galleryDir; 112 134 113 135 XMLParse *m_theme; … … 116 138 QRect m_viewRect; 117 139 118 140 bool m_inMenu; 141 bool m_inSubMenu; 119 142 UIListBtnType *m_menuType; 143 UIListBtnType *m_submenuType; 120 144 121 145 QPixmap m_backRegPix; 122 146 QPixmap m_backSelPix; 123 147 QPixmap m_folderRegPix; 124 148 QPixmap m_folderSelPix; 149 QPixmap m_MrkPix; 125 150 126 151 QString m_currDir; 127 152 bool m_isGallery; 153 #ifndef _WIN32 154 bool m_showDevices; 155 MythMediaDevice *m_currDevice; 156 #endif 128 157 129 158 int m_currRow; 130 159 int m_currCol; … … 143 172 int m_showcaption; 144 173 145 174 typedef void (IconView::*Action)(); 175 176 #ifndef _WIN32 177 public slots: 178 void mediaStatusChanged( MediaStatus oldStatus, MythMediaDevice* pMedia); 179 #endif 146 180 }; 147 181 148 182 -
mythplugins/mythgallery/mythgallery/gallery-ui.xml
21 21 </font> 22 22 23 23 <container name="menu"> 24 <area>20,20,140, 240</area>24 <area>20,20,140,500</area> 25 25 26 26 <listbtnarea name="menu" draworder="0"> 27 27 <area>0,0,140,240</area> … … 35 35 <showscrollarrows>no</showscrollarrows> 36 36 </listbtnarea> 37 37 38 <listbtnarea name="submenu" draworder="0"> 39 <area>0,260,140,240</area> 40 <gradient type="unselected" start="#000000" end="#505050" alpha="100"> 41 </gradient> 42 <gradient type="selected" start="#52CA38" end="#349838" alpha="255"> 43 </gradient> 44 <fcnfont name="active" function="active"></fcnfont> 45 <fcnfont name="inactive" function="inactive"></fcnfont> 46 <showarrow>no</showarrow> 47 <showscrollarrows>no</showscrollarrows> 48 </listbtnarea> 49 38 50 </container> 39 51 40 52 <container name="text"> -
mythplugins/mythgallery/mythgallery/galleryutil.cpp
16 16 * 17 17 * ============================================================ */ 18 18 19 #include <iostream>20 19 #include <qfileinfo.h> 21 20 #include <qdir.h> 22 21 22 #include <mythtv/mythcontext.h> 23 #include <mythtv/mythdbcon.h> 24 #include <mythtv/util.h> 25 23 26 #include "config.h" 24 27 #include "constants.h" 25 28 #include "galleryutil.h" … … 31 34 // include "exif.hpp" 32 35 #endif // EXIF_SUPPORT 33 36 37 #define LOC QString("GalleryUtil:") 38 #define LOC_ERR QString("GalleryUtil, Error:") 39 40 static QFileInfo MakeUnique(const QFileInfo &dest); 41 static QFileInfo MakeUniqueDirectory(const QFileInfo &dest); 42 static bool FileCopy(const QFileInfo &src, const QFileInfo &dst); 43 static bool FileMove(const QFileInfo &src, const QFileInfo &dst); 44 static bool FileDelete(const QFileInfo &file); 45 34 46 bool GalleryUtil::isImage(const char* filePath) 35 47 { 36 48 QFileInfo fi(filePath); … … 81 93 } 82 94 else 83 95 { 84 std::cerr << "Could not load exif data from " << filePath << std::endl; 96 VERBOSE(VB_IMPORTANT, LOC_ERR + 97 QString("Could not load exif data from '%1'") 98 .arg(filePath)); 99 85 100 } 86 101 87 102 delete [] exifvalue; … … 115 130 } 116 131 catch (...) 117 132 { 118 std::cerr << "GalleryUtil: Failed to extract EXIF headers from " 119 << filePath << std::endl; 133 VERBOSE(VB_IMPORTANT, LOC_ERR + 134 QString("Failed to extract EXIF headers from '%1'") 135 .arg(filePath)); 120 136 } 121 137 122 138 return rotateAngle; … … 249 265 } 250 266 else 251 267 { 252 std::cerr << "Could not load exif data from " << filePath << std::endl; 268 VERBOSE(VB_IMPORTANT, LOC_ERR + 269 QString("Could not load exif data from '%1'") 270 .arg(filePath)); 253 271 } 254 272 255 273 delete [] exifvalue; … … 257 275 } 258 276 catch (...) 259 277 { 260 std::cerr << "GalleryUtil: Failed to extract EXIF headers from " 261 << filePath << std::endl; 278 VERBOSE(VB_IMPORTANT, LOC_ERR + 279 QString("Failed to extract EXIF headers from '%1'") 280 .arg(filePath)); 262 281 } 263 282 264 283 return caption; 265 284 } 285 286 bool GalleryUtil::Copy(const QFileInfo &src, QFileInfo &dst) 287 { 288 if (src.isDir()) 289 return CopyDirectory(src, dst); 290 291 dst = MakeUnique(dst); 292 293 if (!FileCopy(src, dst)) 294 return false; 295 296 MSqlQuery query(MSqlQuery::InitCon()); 297 query.prepare("INSERT INTO gallerymetadata (image, keywords, angle) " 298 "SELECT :IMAGENEW , keywords, angle " 299 "FROM gallerymetadata " 300 "WHERE image = :IMAGEOLD"); 301 query.bindValue(":IMAGENEW", dst.absFilePath().utf8()); 302 query.bindValue(":IMAGEOLD", src.absFilePath().utf8()); 303 if (query.exec()) 304 return true; 305 306 // try to undo copy on DB failure 307 FileDelete(dst); 308 return false; 309 } 310 311 bool GalleryUtil::Move(const QFileInfo &src, QFileInfo &dst) 312 { 313 if (src.isDir()) 314 return MoveDirectory(src, dst); 315 316 dst = MakeUnique(dst); 317 318 if (!FileMove(src, dst)) 319 return false; 320 321 MSqlQuery query(MSqlQuery::InitCon()); 322 query.prepare("UPDATE gallerymetadata " 323 "SET image = :IMAGENEW " 324 "WHERE image = :IMAGEOLD"); 325 query.bindValue(":IMAGENEW", dst.absFilePath().utf8()); 326 query.bindValue(":IMAGEOLD", src.absFilePath().utf8()); 327 if (query.exec()) 328 return true; 329 330 // try to undo move on DB failure 331 FileMove(dst, src); 332 return false; 333 } 334 335 bool GalleryUtil::Delete(const QFileInfo &file) 336 { 337 if (!file.exists()) 338 return false; 339 340 if (file.isDir()) 341 return DeleteDirectory(file); 342 343 MSqlQuery query(MSqlQuery::InitCon()); 344 query.prepare("DELETE FROM gallerymetadata " 345 "WHERE image = :IMAGE ;"); 346 query.bindValue(":IMAGE", file.absFilePath().utf8()); 347 if (query.exec()) 348 return FileDelete(file); 349 350 return false; 351 } 352 353 bool GalleryUtil::CopyDirectory(const QFileInfo src, QFileInfo &dst) 354 { 355 QDir srcDir(src.absFilePath()); 356 357 dst = MakeUniqueDirectory(dst); 358 if (!dst.exists()) 359 { 360 srcDir.mkdir(dst.absFilePath()); 361 dst.refresh(); 362 } 363 364 if (!dst.exists() || !dst.isDir()) 365 return false; 366 367 bool ok = true; 368 QDir dstDir(dst.absFilePath()); 369 QFileInfoListIterator it(*srcDir.entryInfoList()); 370 for (; it.current(); ++it) 371 { 372 const QString fn = (it.current())->fileName(); 373 if (fn != "." && fn != "..") 374 { 375 QFileInfo dfi(dstDir, fn); 376 ok &= Copy(*(it.current()), dfi); 377 } 378 } 379 380 return ok; 381 } 382 383 bool GalleryUtil::MoveDirectory(const QFileInfo src, QFileInfo &dst) 384 { 385 QDir srcDir(src.absFilePath()); 386 387 dst = MakeUniqueDirectory(dst); 388 if (!dst.exists()) 389 { 390 srcDir.mkdir(dst.absFilePath()); 391 dst.refresh(); 392 } 393 394 if (!dst.exists() || !dst.isDir()) 395 return false; 396 397 bool ok = true; 398 QDir dstDir(dst.absFilePath()); 399 QFileInfoListIterator it(*srcDir.entryInfoList()); 400 for (; it.current(); ++it) 401 { 402 const QString fn = (it.current())->fileName(); 403 if (fn != "." && fn != "..") 404 { 405 QFileInfo dfi(dstDir, fn); 406 ok &= Move(*(it.current()), dfi); 407 } 408 } 409 410 return ok && FileDelete(src); 411 } 412 413 bool GalleryUtil::DeleteDirectory(const QFileInfo &dir) 414 { 415 if (!dir.exists()) 416 return false; 417 418 QDir srcDir(dir.absFilePath()); 419 QFileInfoListIterator it(*srcDir.entryInfoList()); 420 for (; it.current(); ++it) 421 { 422 const QString fn = (it.current())->fileName(); 423 if (fn != "." && fn != "..") 424 Delete(*(it.current())); 425 } 426 427 return FileDelete(dir); 428 } 429 430 static QFileInfo MakeUnique(const QFileInfo &dest) 431 { 432 QFileInfo newDest = dest; 433 434 for (uint i = 0; newDest.exists(); i++) 435 { 436 QString basename = QString("%1_%2.%3") 437 .arg(dest.baseName(false)).arg(i).arg(dest.extension()); 438 439 newDest.setFile(dest.dir(), basename); 440 441 VERBOSE(VB_GENERAL, LOC_ERR + 442 QString("Need to find a new name for '%1' trying '%2'") 443 .arg(dest.absFilePath()).arg(newDest.absFilePath())); 444 } 445 446 return newDest; 447 } 448 449 static QFileInfo MakeUniqueDirectory(const QFileInfo &dest) 450 { 451 QFileInfo newDest = dest; 452 453 for (uint i = 0; newDest.exists() && !newDest.isDir(); i++) 454 { 455 QString fullname = QString("%1_%2").arg(dest.absFilePath()).arg(i); 456 newDest.setFile(fullname); 457 458 VERBOSE(VB_GENERAL, LOC_ERR + 459 QString("Need to find a new name for '%1' trying '%2'") 460 .arg(dest.absFilePath()).arg(newDest.absFilePath())); 461 } 462 463 return newDest; 464 } 465 466 static bool FileCopy(const QFileInfo &src, const QFileInfo &dst) 467 { 468 QString cmd = "cp "; 469 cmd += "\"" + src.absFilePath().local8Bit() + "\" \""; 470 cmd += dst.absFilePath().local8Bit() + "\""; 471 myth_system(cmd); 472 return true; 473 } 474 475 static bool FileMove(const QFileInfo &src, const QFileInfo &dst) 476 { 477 QString cmd = "mv "; 478 cmd += "\"" + src.absFilePath().local8Bit() + "\" \""; 479 cmd += dst.absFilePath().local8Bit() + "\""; 480 myth_system(cmd); 481 return true; 482 } 483 484 static bool FileDelete(const QFileInfo &file) 485 { 486 if (!file.isDir()) 487 { 488 QString cmd = "rm \"" + file.absFilePath().local8Bit() + "\""; 489 myth_system(cmd); 490 return true; 491 } 492 493 QDir srcDir(file.absFilePath()); 494 srcDir.setNameFilter(MEDIA_FILENAMES); 495 srcDir.setSorting(QDir::Name | QDir::DirsFirst | QDir::IgnoreCase); 496 srcDir.setMatchAllDirs(true); 497 498 // delete .thumbcache 499 QString cmd = "rm -rf \"" + srcDir.absPath().local8Bit(); 500 cmd += "/.thumbcache\""; 501 502 myth_system(cmd); 503 504 srcDir.rmdir(srcDir.absPath()); 505 return true; 506 } 507 508 // Clear marks after operation 509 // Allow wholesale clearing of marks 510 // If there are no marks and operation is delete, 511 // mark then delete selected item 512 // Exit submenu on ESCAPE 513 // Bind DELETE to 'Delete Marked' 514 // Show progress bar while performing operation 515 // Use Qt or C API for renaming/unlinking/copying files or directories. 516 // Exit "Show Devices" on exit from submenu 517 // GetMedias() is unsafe if a device is removed/unmounted while you are 518 // looking at its returned list... 519 // Avoid using #define and #ifdef when possible. -
mythtv/themes/blue/gallery-ui.xml
7 7 8 8 9 9 <container name="menu"> 10 <area>20,20,140, 200</area>10 <area>20,20,140,500</area> 11 11 12 12 <listbtnarea name="menu" draworder="0"> 13 13 <area>0,0,140,200</area> … … 21 21 <showscrollarrows>no</showscrollarrows> 22 22 </listbtnarea> 23 23 24 <listbtnarea name="submenu" draworder="0"> 25 <area>0,220,140,500</area> 26 <gradient type="unselected" start="#000000" end="#505050" alpha="100"> 27 </gradient> 28 <gradient type="selected" start="#52CA38" end="#349838" alpha="255"> 29 </gradient> 30 <fcnfont name="list-active" function="active"></fcnfont> 31 <fcnfont name="list-inactive" function="inactive"></fcnfont> 32 <showarrow>no</showarrow> 33 <showscrollarrows>no</showscrollarrows> 34 </listbtnarea> 35 24 36 </container> 25 37 26 38 <container name="text">