void desktop_drop(BackdropInfo *info,DOpusAppMessage *msg,UWORD qual) { BackdropObject *drop_obj; short ok=0,x,y; char *name,*source_path; short arg,action=DESKTOP_POPUP_LEFTOUT; struct ArgArray *array=0; struct ArgArrayEntry *aae; BOOL check; // Lock backdrop list lock_listlock(&info->objects,0); // See if we dropped stuff on an object if ((drop_obj=backdrop_get_object(info,msg->da_Msg.am_MouseX,msg->da_Msg.am_MouseY,0))) { // Is shift/alt down? if ((qual&(IEQUALIFIER_LSHIFT|IEQUALIFIER_LALT))==(IEQUALIFIER_LSHIFT|IEQUALIFIER_LALT)) { char pathname[256]; // Get path of first file GetWBArgPath(&msg->da_Msg.am_ArgList[0],pathname,256); // Replace the image backdrop_replace_icon_image(info,pathname,drop_obj); // Reply the message ReplyAppMessage(msg); } // Handle drop on an object else if (desktop_drop_on_object(info,&msg,drop_obj,qual)) { // Reply the message ReplyAppMessage(msg); } // Not dropped else drop_obj=0; } // Unlock backdrop list unlock_listlock(&info->objects); // Dropped on an object? if (drop_obj) return; // Get buffer if (!(name=AllocVec(1024,MEMF_CLEAR))) return; source_path=name+512; // Popup menu? if (environment->env->env_flags&ENVF_DESKTOP_FOLDER) { UWORD res; // Activate the underlying menu ActivateWindow(info->window); // Default action set? if (environment->env->desktop_popup_default>DESKTOP_POPUP_NONE && !(qual&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))) { // Use default action action=environment->env->desktop_popup_default; } // Ask user what they want to do else if ((res=DoPopUpMenu(info->window,&GUI->desktop_menu->ph_Menu,0,SELECTDOWN))==(UWORD)-1 || res==MENU_DESKTOP_CANCEL) { // Cancelled FreeVec(name); return; } // Help? else if (res&POPUP_HELPFLAG) { // Do help help_menu_help(res&~POPUP_HELPFLAG,0); // Cancelled FreeVec(name); return; } // Get action else if (res==MENU_DESKTOP_COPY) action=DESKTOP_POPUP_COPY; else if (res==MENU_DESKTOP_MOVE) action=DESKTOP_POPUP_MOVE; } // Set busy pointer SetBusyPointer(info->window); // DOpus message? check=CheckAppMessage(msg); // Go through arguments for (arg=0;arg<msg->da_Msg.am_NumArgs;arg++) { // What operation? switch (action) { // Leave out? case DESKTOP_POPUP_LEFTOUT: // Get path name GetWBArgPath(&msg->da_Msg.am_ArgList[arg],name,512); // Ignore if it's an icon or a disk if (!(isicon(name)) && name[strlen(name)-1]!=':') { short len,perm=0; BackdropObject *icon; // Permanent? if (GUI->flags2&GUIF2_BENIFY) perm=1; // Get position x=msg->da_Msg.am_MouseX; y=msg->da_Msg.am_MouseY; // Drop from DOpus? if (check) { // Adjust position for icon offset x+=msg->da_DragOffset.x+msg->da_DropPos[arg].x; y+=msg->da_DragOffset.y+msg->da_DropPos[arg].y; } // Strip trailing / len=strlen(name)-1; if (name[len]=='/') name[len]=0; // Leave this out if ((icon=backdrop_leave_out(info,name,(perm)?BLOF_PERMANENT:0,x,y))) { // Position it backdrop_place_object(info,icon); // Save for permanent leftout if (perm) backdrop_save_leftouts(info); ok=1; } } break; // Copy/Move case DESKTOP_POPUP_COPY: case DESKTOP_POPUP_MOVE: { BOOL dir=0; // Create ArgArray if needed if (!array && !(array=NewArgArray())) break; // Get path name GetWBArgPath(&msg->da_Msg.am_ArgList[arg],name,512); // Set flag if a directory if (!msg->da_Msg.am_ArgList[arg].wa_Name || !*msg->da_Msg.am_ArgList[arg].wa_Name) dir=1; // Get source path if (!*source_path) { char *ptr; // Copy from name strcpy(source_path,name); // Strip last part if ((ptr=FilePart(source_path))) *ptr=0; } // Create argument if ((aae=NewArgArrayEntry(array,FilePart(name)))) { // Set directory flag if (dir) aae->ae_Flags|=AEF_DIR; // Set OK flag ok=1; } } break; } } // Successful? if (ok) { // Left-outs? if (action==DESKTOP_POPUP_LEFTOUT) { // Refresh backdrop_show_objects(info,BDSF_RECALC); } // Otherwise, launch function else { // Launch the function function_launch( FUNCTION_RUN_FUNCTION_EXTERNAL, (action==DESKTOP_POPUP_COPY)?def_function_copy:def_function_move, 0, FUNCF_ICONS|FUNCF_RESCAN_DESKTOP|FUNCF_DRAG_DROP|FUNCF_COPY_NO_MOVE, 0,0, source_path,environment->env->desktop_location, array, 0, (Buttons *)CopyAppMessage(msg,global_memory_pool)); } } // Otherwise, free array else FreeArgArray(array); // Free buffer FreeVec(name); // Clear busy pointer ClearPointer(info->window); // Reply the message ReplyAppMessage(msg); }
// Run a function on some icons void icon_function(BackdropInfo *info,BackdropObject *only_one,char *data,Cfg_Function *func,ULONG flags) { short count=0; struct ArgArray *array; BackdropObject *object; DirBuffer *buffer=0; char *source_path=0; // Lock backdrop list lock_listlock(&info->objects,1); // Go through backdrop list for (object=(BackdropObject *)info->objects.list.lh_Head; object->node.ln_Succ; object=(BackdropObject *)object->node.ln_Succ) { // Skip invalid icons if (object->type!=BDO_LEFT_OUT || (!info->lister && !(object->flags&BDOF_DESKTOP_FOLDER))) continue; // Want this icon? if (!only_one || only_one==object) { // Is object selected? if ((only_one || object->state) && object->icon) { // Increment counts if (object->icon->do_Type==WBDRAWER || object->icon->do_Type==WBGARBAGE || object->icon->do_Type==WBPROJECT || object->icon->do_Type==WBTOOL) ++count; // Only doing one? if (only_one) break; } } } // Nothing to work on? if (count==0 || !(array=NewArgArray())) { unlock_listlock(&info->objects); return; } // Got a lister? if (info->lister) { // Lock buffer buffer_lock((buffer=info->lister->cur_buffer),FALSE); } // Source path from icon? else if (only_one && only_one->path && (source_path=AllocVec(strlen(only_one->path)+1,0))) strcpy(source_path,only_one->path); // Otherwise, assume this is the desktop folder else if (info->flags&BDIF_MAIN_DESKTOP && (source_path=AllocVec(strlen(environment->env->desktop_location)+1,0))) strcpy(source_path,environment->env->desktop_location); // Go through backdrop list again for (object=(BackdropObject *)info->objects.list.lh_Head; object->node.ln_Succ; object=(BackdropObject *)object->node.ln_Succ) { // Skip invalid icons if (object->type!=BDO_LEFT_OUT || (!info->lister && !(object->flags&BDOF_DESKTOP_FOLDER))) continue; // Want this icon? if (!only_one || only_one==object) { // Is object selected? if ((only_one || object->state) && object->icon) { char name[80]; BOOL dir=0,link=0,icon=0; DirEntry *entry=0; struct ArgArrayEntry *aae; // Build name stccpy(name,object->name,sizeof(name)); // Got a buffer? if (buffer) { // See if we can find this entry if ((entry=find_entry(&buffer->entry_list,object->name,0,buffer->more_flags&DWF_CASE)) || (entry=find_entry(&buffer->reject_list,object->name,0,buffer->more_flags&DWF_CASE))) { // Directory? if (entry->de_Node.dn_Type>=ENTRY_DEVICE) dir=1; // Link? if (entry->de_Flags&ENTF_LINK) link=1; // See if entry has icon if (find_entry(&buffer->entry_list,object->name,0,(buffer->more_flags&DWF_CASE)|FINDENTRY_ICON) || find_entry(&buffer->reject_list,object->name,0,(buffer->more_flags&DWF_CASE)|FINDENTRY_ICON)) icon=1; } // If not, use the .info name else { // Add .info strcat(name,".info"); } } // Desktop folder? else if (info->flags&BDIF_MAIN_DESKTOP) { // Assume the file has an icon icon=1; } // Get type from icon if (!entry) { if (object->icon->do_Type==WBDRAWER || object->icon->do_Type==WBGARBAGE) dir=1; if (object->flags&BDOF_LINK_ICON) link=1; } // Tack on a / for directories if (dir) strcat(name,"/"); // Allocate array entry if (aae=NewArgArrayEntry(array,name)) { // Dir? if (dir) aae->ae_Flags|=AEF_DIR; // Link? if (link) aae->ae_Flags|=AEF_LINK; // No icon? if (!icon) aae->ae_Flags|=AEF_FAKE_ICON; } // Only doing one? if (only_one) break; } } } // Unlock buffer if (buffer) buffer_unlock(buffer); // Get flags we need flags|=(data && *data)?FUNCF_ICONS:FUNCF_ICONS|FUNCF_ASK_DEST; // Launch the function function_launch( FUNCTION_RUN_FUNCTION_EXTERNAL, func, 0, flags, info->lister,0, (info->lister)?info->lister->cur_buffer->buf_Path:source_path,data, array, 0,0); // Free source path FreeVec(source_path); // Unlock list unlock_listlock(&info->objects); }