#include "App.h" #include "MainWindow.h" //#include "common.h" #include //#include "util.h" #include #include #include #include #include App *app; MainWindow *mainwin; LIBMTP_mtpdevice_t *detected_device=0; bool finish_read_device = false; uint64_t prev_progress = 0; int progress (uint64_t const sent, uint64_t const total, void const * const data) { uint64_t progress_percent = (100*sent)/total; if (((progress_percent % 10) == 0) && (progress_percent > prev_progress) && (total>10*1024*1024)){ printf(" Progress %d\n", progress_percent); mainwin->uploadDownloadNotification->SetProgress((float)sent/total); prev_progress = (progress_percent < 100)? progress_percent: 0; mainwin->uploadDownloadNotification->Send(); } return 0; } /* Find the file type based on extension */ LIBMTP_filetype_t find_filetype (const char * filename) { char *ptype; LIBMTP_filetype_t filetype; #ifdef __WIN32__ ptype = strrchr(filename, '.'); #else ptype = rindex(filename,'.'); #endif // This accounts for the case with a filename without any "." (period). if (!ptype) { ptype = ""; } else { ++ptype; } /* This need to be kept constantly updated as new file types arrive. */ if (!strcasecmp (ptype, "wav")) { filetype = LIBMTP_FILETYPE_WAV; } else if (!strcasecmp (ptype, "mp3")) { filetype = LIBMTP_FILETYPE_MP3; } else if (!strcasecmp (ptype, "wma")) { filetype = LIBMTP_FILETYPE_WMA; } else if (!strcasecmp (ptype, "ogg")) { filetype = LIBMTP_FILETYPE_OGG; } else if (!strcasecmp (ptype, "mp4")) { filetype = LIBMTP_FILETYPE_MP4; } else if (!strcasecmp (ptype, "wmv")) { filetype = LIBMTP_FILETYPE_WMV; } else if (!strcasecmp (ptype, "avi")) { filetype = LIBMTP_FILETYPE_AVI; } else if (!strcasecmp (ptype, "mpeg") || !strcasecmp (ptype, "mpg")) { filetype = LIBMTP_FILETYPE_MPEG; } else if (!strcasecmp (ptype, "asf")) { filetype = LIBMTP_FILETYPE_ASF; } else if (!strcasecmp (ptype, "qt") || !strcasecmp (ptype, "mov")) { filetype = LIBMTP_FILETYPE_QT; } else if (!strcasecmp (ptype, "wma")) { filetype = LIBMTP_FILETYPE_WMA; } else if (!strcasecmp (ptype, "jpg") || !strcasecmp (ptype, "jpeg")) { filetype = LIBMTP_FILETYPE_JPEG; } else if (!strcasecmp (ptype, "jfif")) { filetype = LIBMTP_FILETYPE_JFIF; } else if (!strcasecmp (ptype, "tif") || !strcasecmp (ptype, "tiff")) { filetype = LIBMTP_FILETYPE_TIFF; } else if (!strcasecmp (ptype, "bmp")) { filetype = LIBMTP_FILETYPE_BMP; } else if (!strcasecmp (ptype, "gif")) { filetype = LIBMTP_FILETYPE_GIF; } else if (!strcasecmp (ptype, "pic") || !strcasecmp (ptype, "pict")) { filetype = LIBMTP_FILETYPE_PICT; } else if (!strcasecmp (ptype, "png")) { filetype = LIBMTP_FILETYPE_PNG; } else if (!strcasecmp (ptype, "wmf")) { filetype = LIBMTP_FILETYPE_WINDOWSIMAGEFORMAT; } else if (!strcasecmp (ptype, "ics")) { filetype = LIBMTP_FILETYPE_VCALENDAR2; } else if (!strcasecmp (ptype, "exe") || !strcasecmp (ptype, "com") || !strcasecmp (ptype, "bat") || !strcasecmp (ptype, "dll") || !strcasecmp (ptype, "sys")) { filetype = LIBMTP_FILETYPE_WINEXEC; } else if (!strcasecmp (ptype, "aac")) { filetype = LIBMTP_FILETYPE_AAC; } else if (!strcasecmp (ptype, "mp2")) { filetype = LIBMTP_FILETYPE_MP2; } else if (!strcasecmp (ptype, "flac")) { filetype = LIBMTP_FILETYPE_FLAC; } else if (!strcasecmp (ptype, "m4a")) { filetype = LIBMTP_FILETYPE_M4A; } else if (!strcasecmp (ptype, "doc")) { filetype = LIBMTP_FILETYPE_DOC; } else if (!strcasecmp (ptype, "xml")) { filetype = LIBMTP_FILETYPE_XML; } else if (!strcasecmp (ptype, "xls")) { filetype = LIBMTP_FILETYPE_XLS; } else if (!strcasecmp (ptype, "ppt")) { filetype = LIBMTP_FILETYPE_PPT; } else if (!strcasecmp (ptype, "mht")) { filetype = LIBMTP_FILETYPE_MHT; } else if (!strcasecmp (ptype, "jp2")) { filetype = LIBMTP_FILETYPE_JP2; } else if (!strcasecmp (ptype, "jpx")) { filetype = LIBMTP_FILETYPE_JPX; } else if (!strcasecmp (ptype, "bin")) { filetype = LIBMTP_FILETYPE_FIRMWARE; } else if (!strcasecmp (ptype, "vcf")) { filetype = LIBMTP_FILETYPE_VCARD3; } else { /* Tagging as unknown file type */ filetype = LIBMTP_FILETYPE_UNKNOWN; } printf("type: %s, %d\n", ptype, filetype); return filetype; } static char *basename(char *in) { char *p; if (in == NULL) return NULL; p = in + strlen(in) - 1; while (*p != '\\' && *p != '/' && *p != ':') { p--; } return ++p; } int sendfile_function(char * from_path, int32_t parent_id, int32_t & ret_newFileID) { //printf("Sending %s to %s\n",from_path,to_path); char *filename; uint64_t filesize; struct stat sb; LIBMTP_file_t *genfile; int ret; //uint32_t parent_id = 0; if ( stat(from_path, &sb) == -1 ) { fprintf(stderr, "%s: ", from_path); perror("stat"); return 1; } filesize = sb.st_size; filename = basename(from_path); //parent_id = parse_path (to_path,files,folders); if (parent_id == -1) { printf("Parent folder could not be found, skipping\n"); return 0; } genfile = LIBMTP_new_file_t(); genfile->filesize = filesize; genfile->filename = strdup(filename); genfile->filetype = find_filetype (filename); genfile->parent_id = parent_id; genfile->storage_id = 0; printf("Sending file...\n"); ret = LIBMTP_Send_File_From_File(detected_device, from_path, genfile, progress, NULL); printf("\n"); if (ret != 0) { printf("Error sending file.\n"); LIBMTP_Dump_Errorstack(detected_device); LIBMTP_Clear_Errorstack(detected_device); ret = 1; } else { printf("New file ID: %d\n", genfile->item_id); ret_newFileID = genfile->item_id; } LIBMTP_destroy_file_t(genfile); return ret; } /* Clever prototype to be able to recurse */ void recursive_file_tree(LIBMTP_mtpdevice_t *, LIBMTP_devicestorage_t *, uint32_t, int); void recursive_file_tree(LIBMTP_mtpdevice_t *device, LIBMTP_devicestorage_t *storage, uint32_t leaf, int depth) { LIBMTP_file_t *files; LIBMTP_file_t *file; files = LIBMTP_Get_Files_And_Folders(device, storage->id, leaf); if (files == NULL) { return; } /* Iterate over the filelisting */ file = files; while (file != NULL) { LIBMTP_file_t *oldfile; if (strcmp(file->filename, "Android")!=0) //skip system folder { /* Indent */ /* int i; for (i = 0; i < depth; i++) { printf(" "); } printf("%u %s\n", file->item_id, file->filename);*/ mainwin->listView()->AddItem(new FileItem(device, storage, file->item_id, file->filename, file->filetype != LIBMTP_FILETYPE_FOLDER, depth)); if (file->filetype == LIBMTP_FILETYPE_FOLDER) { recursive_file_tree(device, storage, file->item_id, depth+1); } } oldfile = file; file = file->next; LIBMTP_destroy_file_t(oldfile); } } void file_list(LIBMTP_mtpdevice_t *device, LIBMTP_devicestorage_t *storage, uint32_t leaf, int depth, BListItem * parentItem = NULL) { LIBMTP_file_t *files; LIBMTP_file_t *file; files = LIBMTP_Get_Files_And_Folders(device, storage->id, leaf); if (files == NULL) { return; } /* Iterate over the filelisting */ file = files; while (file != NULL) { LIBMTP_file_t *oldfile; if (strcmp(file->filename, "Android")!=0) //skip system folder { FileItem * newItem = new FileItem(device, storage, file->item_id, file->filename, file->filetype != LIBMTP_FILETYPE_FOLDER, depth); if (parentItem == NULL) { mainwin->listView()->AddItem(newItem); } else { mainwin->listView()->AddUnder(newItem, parentItem); } /* if (file->filetype == LIBMTP_FILETYPE_FOLDER) { recursive_file_tree(device, storage, file->item_id, depth+1); }*/ } oldfile = file; file = file->next; LIBMTP_destroy_file_t(oldfile); } } int init_mtp (/*int argc, char **argv*/) { LIBMTP_raw_device_t * rawdevices; int numrawdevices; LIBMTP_error_number_t err; int i; LIBMTP_Init(); err = LIBMTP_Detect_Raw_Devices(&rawdevices, &numrawdevices); switch(err) { case LIBMTP_ERROR_NO_DEVICE_ATTACHED: fprintf(stdout, " No raw devices found.\n"); mainwin->showErrorAlert("No raw devices found. Be sure device connected and configured transfer mode."); return 0; case LIBMTP_ERROR_CONNECTING: fprintf(stderr, "Detect: There has been an error connecting. Exiting\n"); mainwin->showErrorAlert("There has been an error connecting."); return 1; case LIBMTP_ERROR_MEMORY_ALLOCATION: fprintf(stderr, "Detect: Encountered a Memory Allocation Error. Exiting\n"); mainwin->showErrorAlert("Encountered a Memory Allocation Error."); return 1; case LIBMTP_ERROR_NONE: break; case LIBMTP_ERROR_GENERAL: default: fprintf(stderr, "Unknown connection error.\n"); mainwin->showErrorAlert("Unknown connection error."); return 1; } /* Iterate over connected MTP devices */ fprintf(stdout, "Attempting to connect device(s)\n"); for (i = 0; i < numrawdevices; i++) { LIBMTP_mtpdevice_t *device; LIBMTP_devicestorage_t *storage; char *friendlyname; int ret; device = LIBMTP_Open_Raw_Device_Uncached(&rawdevices[i]); if (device == NULL) { fprintf(stderr, "Unable to open raw device %d\n", i); mainwin->showErrorAlert("Unable to open raw device."); continue; } detected_device = device; LIBMTP_Dump_Errorstack(device); LIBMTP_Clear_Errorstack(device); friendlyname = LIBMTP_Get_Friendlyname(device); if (friendlyname == NULL) { printf("Device: (NULL)\n"); } else { printf("Device: %s\n", friendlyname); //LIBMTP_FreeMemory(friendlyname); } /* Get all storages for this device */ ret = LIBMTP_Get_Storage(device, LIBMTP_STORAGE_SORTBY_NOTSORTED); if (ret != 0) { perror("LIBMTP_Get_Storage()"); goto bailout; } /* Loop over storages */ for (storage = device->storage; storage != 0; storage = storage->next) { fprintf(stdout, "Storage: %s\n", storage->StorageDescription); //recursive_file_tree(device, storage, LIBMTP_FILES_AND_FOLDERS_ROOT, 0); file_list (device, storage, LIBMTP_FILES_AND_FOLDERS_ROOT, 0); } continue; //do not release device because later use bailout: LIBMTP_Release_Device(device); } /* End For Loop */ //LIBMTP_FreeMemory(rawdevices); missing in current libmtp.h printf("OK.\n"); return 0; } App::App(void) : BApplication("application/x-vnd.dw-ListColors") { mainwin = new MainWindow(); init_mtp(); mainwin->Show(); } void App::AppActivated(bool active) { fprintf(stdout, "App activated\n"); } bool add_sub_files (BListItem * item, void* arg) { FileItem * fileItem =((FileItem * ) item ); if (fileItem->isFolder() && mainwin->listView()->CountItemsUnder(item, true) == 0) { fprintf(stdout, "Getting sub files for %d\n", fileItem->fileId()); file_list(fileItem->device(), fileItem->storage(), fileItem->fileId(), fileItem->OutlineLevel() +1, fileItem); } return false; } void App::ReadyToRun() { fprintf(stdout, "App ready to run\n"); mainwin->listView()->DoForEach(&add_sub_files, NULL); mainwin->listView()->FullListDoForEach(&add_sub_files, NULL); finish_read_device = true; } int main(void) { app = new App(); app->Run(); delete app; return 0; }