102be5353SAxel Dörfler /* 202be5353SAxel Dörfler Open Tracker License 302be5353SAxel Dörfler 402be5353SAxel Dörfler Terms and Conditions 502be5353SAxel Dörfler 602be5353SAxel Dörfler Copyright (c) 1991-2000, Be Incorporated. All rights reserved. 702be5353SAxel Dörfler 802be5353SAxel Dörfler Permission is hereby granted, free of charge, to any person obtaining a copy of 902be5353SAxel Dörfler this software and associated documentation files (the "Software"), to deal in 1002be5353SAxel Dörfler the Software without restriction, including without limitation the rights to 1102be5353SAxel Dörfler use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 1202be5353SAxel Dörfler of the Software, and to permit persons to whom the Software is furnished to do 1302be5353SAxel Dörfler so, subject to the following conditions: 1402be5353SAxel Dörfler 1502be5353SAxel Dörfler The above copyright notice and this permission notice applies to all licensees 1602be5353SAxel Dörfler and shall be included in all copies or substantial portions of the Software.. 1702be5353SAxel Dörfler 1802be5353SAxel Dörfler THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1902be5353SAxel Dörfler IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, 2002be5353SAxel Dörfler FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2102be5353SAxel Dörfler BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2202be5353SAxel Dörfler AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION 2302be5353SAxel Dörfler WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2402be5353SAxel Dörfler 2502be5353SAxel Dörfler Except as contained in this notice, the name of Be Incorporated shall not be 2602be5353SAxel Dörfler used in advertising or otherwise to promote the sale, use or other dealings in 2702be5353SAxel Dörfler this Software without prior written authorization from Be Incorporated. 2802be5353SAxel Dörfler 2902be5353SAxel Dörfler Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks 3002be5353SAxel Dörfler of Be Incorporated in the United States and other countries. Other brand product 3102be5353SAxel Dörfler names are registered trademarks or trademarks of their respective holders. 3202be5353SAxel Dörfler All rights reserved. 3302be5353SAxel Dörfler */ 3402be5353SAxel Dörfler 3502be5353SAxel Dörfler #include "FSClipboard.h" 3602be5353SAxel Dörfler #include <Clipboard.h> 3702be5353SAxel Dörfler #include <Alert.h> 3802be5353SAxel Dörfler #include <NodeMonitor.h> 3902be5353SAxel Dörfler #include "Commands.h" 4002be5353SAxel Dörfler #include "FSUtils.h" 4102be5353SAxel Dörfler #include "Tracker.h" 4202be5353SAxel Dörfler 4302be5353SAxel Dörfler // prototypes 4402be5353SAxel Dörfler static void MakeNodeFromName(node_ref *node, char *name); 4502be5353SAxel Dörfler static inline void MakeRefName(char *refName, const node_ref *node); 4602be5353SAxel Dörfler static inline void MakeModeName(char *modeName, const node_ref *node); 4702be5353SAxel Dörfler static inline void MakeModeNameFromRefName(char *modeName, char *refName); 4802be5353SAxel Dörfler static inline bool CompareModeAndRefName(const char *modeName, const char *refName); 4902be5353SAxel Dörfler 5002be5353SAxel Dörfler 5102be5353SAxel Dörfler //these are from PoseView.cpp 5202be5353SAxel Dörfler extern const char *kNoCopyToTrashStr; 5302be5353SAxel Dörfler extern const char *kNoCopyToRootStr; 5402be5353SAxel Dörfler extern const char *kOkToMoveStr; 5502be5353SAxel Dörfler 5602be5353SAxel Dörfler /* 5702be5353SAxel Dörfler static bool 5802be5353SAxel Dörfler FSClipboardCheckIntegrity() 5902be5353SAxel Dörfler { 6002be5353SAxel Dörfler return true; 6102be5353SAxel Dörfler } 6202be5353SAxel Dörfler */ 6302be5353SAxel Dörfler 647befa79aSAxel Dörfler static void 657befa79aSAxel Dörfler MakeNodeFromName(node_ref *node, char *name) 667befa79aSAxel Dörfler { 677befa79aSAxel Dörfler char *nodeString = strchr(name, '_'); 687befa79aSAxel Dörfler if (nodeString != NULL) { 697befa79aSAxel Dörfler node->node = strtoll(nodeString + 1, (char **)NULL, 10); 707befa79aSAxel Dörfler node->device = atoi(name + 1); 717befa79aSAxel Dörfler } 727befa79aSAxel Dörfler } 737befa79aSAxel Dörfler 747befa79aSAxel Dörfler 757befa79aSAxel Dörfler static inline void 767befa79aSAxel Dörfler MakeRefName(char *refName, const node_ref *node) 777befa79aSAxel Dörfler { 787befa79aSAxel Dörfler sprintf(refName, "r%ld_%Ld", node->device, node->node); 797befa79aSAxel Dörfler } 807befa79aSAxel Dörfler 817befa79aSAxel Dörfler 827befa79aSAxel Dörfler static inline void 837befa79aSAxel Dörfler MakeModeName(char *modeName, const node_ref *node) 847befa79aSAxel Dörfler { 857befa79aSAxel Dörfler sprintf(modeName, "m%ld_%Ld", node->device, node->node); 867befa79aSAxel Dörfler } 877befa79aSAxel Dörfler 887befa79aSAxel Dörfler 897befa79aSAxel Dörfler static inline void 907befa79aSAxel Dörfler MakeModeName(char *name) 917befa79aSAxel Dörfler { 927befa79aSAxel Dörfler name[0] = 'm'; 937befa79aSAxel Dörfler } 947befa79aSAxel Dörfler 957befa79aSAxel Dörfler 967befa79aSAxel Dörfler static inline void 977befa79aSAxel Dörfler MakeModeNameFromRefName(char *modeName, char *refName) 987befa79aSAxel Dörfler { 997befa79aSAxel Dörfler strcpy(modeName, refName); 1007befa79aSAxel Dörfler modeName[0] = 'm'; 1017befa79aSAxel Dörfler } 1027befa79aSAxel Dörfler 1037befa79aSAxel Dörfler 1047befa79aSAxel Dörfler static inline bool 1057befa79aSAxel Dörfler CompareModeAndRefName(const char *modeName, const char *refName) 1067befa79aSAxel Dörfler { 1077befa79aSAxel Dörfler return !strcmp(refName + 1, modeName + 1); 1087befa79aSAxel Dörfler } 1097befa79aSAxel Dörfler 1107befa79aSAxel Dörfler 1117befa79aSAxel Dörfler // #pragma mark - 1127befa79aSAxel Dörfler 1137befa79aSAxel Dörfler 11402be5353SAxel Dörfler bool 11502be5353SAxel Dörfler FSClipboardHasRefs() 11602be5353SAxel Dörfler { 11702be5353SAxel Dörfler bool result = false; 11802be5353SAxel Dörfler 11902be5353SAxel Dörfler if (be_clipboard->Lock()) { 12002be5353SAxel Dörfler BMessage *clip = be_clipboard->Data(); 12102be5353SAxel Dörfler if (clip != NULL) { 12202be5353SAxel Dörfler #ifdef B_BEOS_VERSION_DANO 12302be5353SAxel Dörfler const 12402be5353SAxel Dörfler #endif 12502be5353SAxel Dörfler char *refName; 12602be5353SAxel Dörfler #ifdef B_BEOS_VERSION_DANO 12702be5353SAxel Dörfler const 12802be5353SAxel Dörfler #endif 12902be5353SAxel Dörfler char *modeName; 13002be5353SAxel Dörfler uint32 type; 13102be5353SAxel Dörfler int32 count; 13202be5353SAxel Dörfler if (clip->GetInfo(B_REF_TYPE, 0, &refName, &type, &count) == B_OK 13302be5353SAxel Dörfler && clip->GetInfo(B_INT32_TYPE, 0, &modeName, &type, &count) == B_OK) 13402be5353SAxel Dörfler result = CompareModeAndRefName(modeName, refName); 13502be5353SAxel Dörfler } 13602be5353SAxel Dörfler be_clipboard->Unlock(); 13702be5353SAxel Dörfler } 13802be5353SAxel Dörfler return result; 13902be5353SAxel Dörfler } 14002be5353SAxel Dörfler 14102be5353SAxel Dörfler 14202be5353SAxel Dörfler void 14302be5353SAxel Dörfler FSClipboardStartWatch(BMessenger target) 14402be5353SAxel Dörfler { 14502be5353SAxel Dörfler if (dynamic_cast<TTracker *>(be_app) != NULL) 14602be5353SAxel Dörfler ((TTracker *)be_app)->ClipboardRefsWatcher()->AddToNotifyList(target); 14702be5353SAxel Dörfler else { 14802be5353SAxel Dörfler // this code is used by external apps using objects using FSClipboard functions 14902be5353SAxel Dörfler // i.e: applications using FilePanel 15002be5353SAxel Dörfler BMessenger messenger(kTrackerSignature); 15102be5353SAxel Dörfler if (messenger.IsValid()) { 15202be5353SAxel Dörfler BMessage message(kStartWatchClipboardRefs); 15302be5353SAxel Dörfler message.AddMessenger("target", target); 15402be5353SAxel Dörfler messenger.SendMessage(&message); 15502be5353SAxel Dörfler } 15602be5353SAxel Dörfler } 15702be5353SAxel Dörfler } 15802be5353SAxel Dörfler 15902be5353SAxel Dörfler 16002be5353SAxel Dörfler void 16102be5353SAxel Dörfler FSClipboardStopWatch(BMessenger target) 16202be5353SAxel Dörfler { 16302be5353SAxel Dörfler if (dynamic_cast<TTracker *>(be_app) != NULL) 16402be5353SAxel Dörfler ((TTracker *)be_app)->ClipboardRefsWatcher()->AddToNotifyList(target); 16502be5353SAxel Dörfler else { 16602be5353SAxel Dörfler // this code is used by external apps using objects using FSClipboard functions 16702be5353SAxel Dörfler // i.e: applications using FilePanel 16802be5353SAxel Dörfler BMessenger messenger(kTrackerSignature); 16902be5353SAxel Dörfler if (messenger.IsValid()) { 17002be5353SAxel Dörfler BMessage message(kStopWatchClipboardRefs); 17102be5353SAxel Dörfler message.AddMessenger("target", target); 17202be5353SAxel Dörfler messenger.SendMessage(&message); 17302be5353SAxel Dörfler } 17402be5353SAxel Dörfler } 17502be5353SAxel Dörfler } 17602be5353SAxel Dörfler 17702be5353SAxel Dörfler 17802be5353SAxel Dörfler void 17902be5353SAxel Dörfler FSClipboardClear() 18002be5353SAxel Dörfler { 18102be5353SAxel Dörfler if (!be_clipboard->Lock()) 18202be5353SAxel Dörfler return; 18302be5353SAxel Dörfler 18402be5353SAxel Dörfler be_clipboard->Clear(); 18502be5353SAxel Dörfler be_clipboard->Commit(); 18602be5353SAxel Dörfler be_clipboard->Unlock(); 18702be5353SAxel Dörfler } 18802be5353SAxel Dörfler 18902be5353SAxel Dörfler 19002be5353SAxel Dörfler /** This function adds the given poses list to the clipboard, for both copy 19102be5353SAxel Dörfler * and cut. All poses in the list must have "directory" as parent. 19202be5353SAxel Dörfler * "moveMode" is either kMoveSelection or kCopySelection. 19302be5353SAxel Dörfler * It will check if the entries are already present, so that there can only 19402be5353SAxel Dörfler * be one reference to them in the clipboard. 19502be5353SAxel Dörfler */ 19602be5353SAxel Dörfler 19702be5353SAxel Dörfler uint32 19802be5353SAxel Dörfler FSClipboardAddPoses(const node_ref *directory, PoseList *list, uint32 moveMode, 19902be5353SAxel Dörfler bool clearClipboard) 20002be5353SAxel Dörfler { 20102be5353SAxel Dörfler uint32 refsAdded = 0; 20202be5353SAxel Dörfler int32 listCount = list->CountItems(); 20302be5353SAxel Dörfler 20402be5353SAxel Dörfler if (listCount == 0 || !be_clipboard->Lock()) 20502be5353SAxel Dörfler return 0; 20602be5353SAxel Dörfler 20702be5353SAxel Dörfler // update message to be send to all listeners 20802be5353SAxel Dörfler BMessage updateMessage(kFSClipboardChanges); 20902be5353SAxel Dörfler updateMessage.AddInt32("device", directory->device); 21002be5353SAxel Dörfler updateMessage.AddInt64("directory", directory->node); 21102be5353SAxel Dörfler updateMessage.AddBool("clearClipboard", clearClipboard); 21202be5353SAxel Dörfler 21302be5353SAxel Dörfler TClipboardNodeRef clipNode; 21402be5353SAxel Dörfler clipNode.moveMode = moveMode; 21502be5353SAxel Dörfler 21602be5353SAxel Dörfler if (clearClipboard) 21702be5353SAxel Dörfler be_clipboard->Clear(); 21802be5353SAxel Dörfler 21902be5353SAxel Dörfler BMessage *clip = be_clipboard->Data(); 22002be5353SAxel Dörfler if (clip != NULL) { 22102be5353SAxel Dörfler for (int32 index = 0; index < listCount; index++) { 22202be5353SAxel Dörfler char refName[64], modeName[64]; 22302be5353SAxel Dörfler BPose *pose = (BPose *)list->ItemAt(index); 22402be5353SAxel Dörfler Model *model = pose->TargetModel(); 22502be5353SAxel Dörfler const node_ref *node = model->NodeRef(); 22602be5353SAxel Dörfler 22702be5353SAxel Dörfler BEntry entry; 22802be5353SAxel Dörfler model->GetEntry(&entry); 22902be5353SAxel Dörfler if (model->IsVolume() 23002be5353SAxel Dörfler || model->IsRoot() 231d9626569SRene Gollent || model->IsTrash() 232*89af0548SRene Gollent || model->IsDesktop()) 23302be5353SAxel Dörfler continue; 23402be5353SAxel Dörfler 23502be5353SAxel Dörfler MakeRefName(refName, node); 23602be5353SAxel Dörfler MakeModeNameFromRefName(modeName, refName); 23702be5353SAxel Dörfler 23802be5353SAxel Dörfler if (clearClipboard) { 2395422febdSStephan Aßmus if (clip->AddInt32(modeName, (int32)moveMode) == B_OK) { 24002be5353SAxel Dörfler if (clip->AddRef(refName, model->EntryRef()) == B_OK) { 24102be5353SAxel Dörfler pose->SetClipboardMode(moveMode); 24202be5353SAxel Dörfler 24302be5353SAxel Dörfler clipNode.node = *node; 2445422febdSStephan Aßmus updateMessage.AddData("tcnode", T_CLIPBOARD_NODE, 2455422febdSStephan Aßmus &clipNode, sizeof(TClipboardNodeRef), true, 2465422febdSStephan Aßmus listCount); 24702be5353SAxel Dörfler 24802be5353SAxel Dörfler refsAdded++; 24902be5353SAxel Dörfler } else 25002be5353SAxel Dörfler clip->RemoveName(modeName); 2515422febdSStephan Aßmus } 25202be5353SAxel Dörfler } else { 25302be5353SAxel Dörfler if (clip->ReplaceInt32(modeName, (int32)moveMode) == B_OK) { 25402be5353SAxel Dörfler // replace old mode if entry already exists in clipboard 25502be5353SAxel Dörfler if (clip->ReplaceRef(refName, model->EntryRef()) == B_OK) { 25602be5353SAxel Dörfler pose->SetClipboardMode(moveMode); 25702be5353SAxel Dörfler 25802be5353SAxel Dörfler clipNode.node = *node; 2595422febdSStephan Aßmus updateMessage.AddData("tcnode", T_CLIPBOARD_NODE, 2605422febdSStephan Aßmus &clipNode, sizeof(TClipboardNodeRef), true, 2615422febdSStephan Aßmus listCount); 26202be5353SAxel Dörfler 26302be5353SAxel Dörfler refsAdded++; 26402be5353SAxel Dörfler } else { 26502be5353SAxel Dörfler clip->RemoveName(modeName); 26602be5353SAxel Dörfler 26702be5353SAxel Dörfler clipNode.node = *node; 26802be5353SAxel Dörfler clipNode.moveMode = kDelete; // note removing node 2695422febdSStephan Aßmus updateMessage.AddData("tcnode", T_CLIPBOARD_NODE, 2705422febdSStephan Aßmus &clipNode, sizeof(TClipboardNodeRef), true, 2715422febdSStephan Aßmus listCount); 2725422febdSStephan Aßmus clipNode.moveMode = moveMode; 2735422febdSStephan Aßmus // set it back to current value 27402be5353SAxel Dörfler } 27502be5353SAxel Dörfler } else { 2767befa79aSAxel Dörfler // add it if it doesn't exist 27702be5353SAxel Dörfler if (clip->AddRef(refName, model->EntryRef()) == B_OK 27802be5353SAxel Dörfler && clip->AddInt32(modeName, (int32)moveMode) == B_OK) { 27902be5353SAxel Dörfler pose->SetClipboardMode(moveMode); 28002be5353SAxel Dörfler 28102be5353SAxel Dörfler clipNode.node = *node; 2825422febdSStephan Aßmus updateMessage.AddData("tcnode", T_CLIPBOARD_NODE, 2835422febdSStephan Aßmus &clipNode, sizeof(TClipboardNodeRef), true, 2845422febdSStephan Aßmus listCount); 28502be5353SAxel Dörfler 28602be5353SAxel Dörfler refsAdded++; 28702be5353SAxel Dörfler } else { 28802be5353SAxel Dörfler clip->RemoveName(modeName); 28902be5353SAxel Dörfler clip->RemoveName(refName); 2907befa79aSAxel Dörfler // here notifying delete isn't needed as node didn't 2917befa79aSAxel Dörfler // exist in clipboard 29202be5353SAxel Dörfler } 29302be5353SAxel Dörfler } 29402be5353SAxel Dörfler } 29502be5353SAxel Dörfler } 29602be5353SAxel Dörfler be_clipboard->Commit(); 29702be5353SAxel Dörfler } 29802be5353SAxel Dörfler be_clipboard->Unlock(); 29902be5353SAxel Dörfler 30002be5353SAxel Dörfler BMessenger(kTrackerSignature).SendMessage(&updateMessage); 30102be5353SAxel Dörfler // Tracker will notify all listeners 30202be5353SAxel Dörfler 30302be5353SAxel Dörfler return refsAdded; 30402be5353SAxel Dörfler } 30502be5353SAxel Dörfler 30602be5353SAxel Dörfler 30702be5353SAxel Dörfler uint32 30802be5353SAxel Dörfler FSClipboardRemovePoses(const node_ref *directory, PoseList *list) 30902be5353SAxel Dörfler { 31002be5353SAxel Dörfler if (!be_clipboard->Lock()) 31102be5353SAxel Dörfler return 0; 31202be5353SAxel Dörfler 31302be5353SAxel Dörfler // update message to be send to all listeners 31402be5353SAxel Dörfler BMessage updateMessage(kFSClipboardChanges); 31502be5353SAxel Dörfler updateMessage.AddInt32("device", directory->device); 31602be5353SAxel Dörfler updateMessage.AddInt64("directory", directory->node); 31702be5353SAxel Dörfler updateMessage.AddBool("clearClipboard", false); 31802be5353SAxel Dörfler 31902be5353SAxel Dörfler TClipboardNodeRef clipNode; 32002be5353SAxel Dörfler clipNode.moveMode = kDelete; 32102be5353SAxel Dörfler 32202be5353SAxel Dörfler uint32 refsRemoved = 0; 32302be5353SAxel Dörfler 32402be5353SAxel Dörfler BMessage *clip = be_clipboard->Data(); 32502be5353SAxel Dörfler if (clip != NULL) { 32602be5353SAxel Dörfler int32 listCount = list->CountItems(); 32702be5353SAxel Dörfler 32802be5353SAxel Dörfler for (int32 index = 0; index < listCount; index++) { 32902be5353SAxel Dörfler char refName[64], modeName[64]; 33002be5353SAxel Dörfler BPose *pose = (BPose *)list->ItemAt(index); 33102be5353SAxel Dörfler 33202be5353SAxel Dörfler clipNode.node = *pose->TargetModel()->NodeRef(); 33302be5353SAxel Dörfler MakeRefName(refName, &clipNode.node); 33402be5353SAxel Dörfler MakeModeName(modeName); 33502be5353SAxel Dörfler 33602be5353SAxel Dörfler if (clip->RemoveName(refName) == B_OK && clip->RemoveName(modeName)) { 33702be5353SAxel Dörfler updateMessage.AddData("tcnode", T_CLIPBOARD_NODE, &clipNode, 33802be5353SAxel Dörfler sizeof(TClipboardNodeRef), true, listCount); 33902be5353SAxel Dörfler refsRemoved++; 34002be5353SAxel Dörfler } 34102be5353SAxel Dörfler } 34202be5353SAxel Dörfler be_clipboard->Commit(); 34302be5353SAxel Dörfler } 34402be5353SAxel Dörfler be_clipboard->Unlock(); 34502be5353SAxel Dörfler 34602be5353SAxel Dörfler BMessenger(kTrackerSignature).SendMessage(&updateMessage); 34702be5353SAxel Dörfler // Tracker will notify all listeners 34802be5353SAxel Dörfler 34902be5353SAxel Dörfler return refsRemoved; 35002be5353SAxel Dörfler } 35102be5353SAxel Dörfler 35202be5353SAxel Dörfler 35302be5353SAxel Dörfler /** Pastes entries from the clipboard to the target model's directory. 35402be5353SAxel Dörfler * Updates moveModes and notifies listeners if necessary. 35502be5353SAxel Dörfler */ 35602be5353SAxel Dörfler 35702be5353SAxel Dörfler bool 35802be5353SAxel Dörfler FSClipboardPaste(Model *model, uint32 linksMode) 35902be5353SAxel Dörfler { 36002be5353SAxel Dörfler if (!FSClipboardHasRefs()) 36102be5353SAxel Dörfler return false; 36202be5353SAxel Dörfler 36302be5353SAxel Dörfler BMessenger tracker(kTrackerSignature); 36402be5353SAxel Dörfler 36502be5353SAxel Dörfler node_ref *destNodeRef = (node_ref *)model->NodeRef(); 36602be5353SAxel Dörfler 36702be5353SAxel Dörfler // these will be passed to the asynchronous copy/move process 36802be5353SAxel Dörfler BObjectList<entry_ref> *moveList = new BObjectList<entry_ref>(0, true); 36902be5353SAxel Dörfler BObjectList<entry_ref> *copyList = new BObjectList<entry_ref>(0, true); 37002be5353SAxel Dörfler 37102be5353SAxel Dörfler if ((be_clipboard->Lock())) { 37202be5353SAxel Dörfler BMessage *clip = be_clipboard->Data(); 37302be5353SAxel Dörfler if (clip != NULL) { 37402be5353SAxel Dörfler char modeName[64]; 37502be5353SAxel Dörfler uint32 moveMode = 0; 37602be5353SAxel Dörfler 37702be5353SAxel Dörfler BMessage *updateMessage = NULL; 37802be5353SAxel Dörfler node_ref updateNodeRef; 37902be5353SAxel Dörfler updateNodeRef.device = -1; 38002be5353SAxel Dörfler 38102be5353SAxel Dörfler char *refName; 38202be5353SAxel Dörfler type_code type; 38302be5353SAxel Dörfler int32 count; 38402be5353SAxel Dörfler for (int32 index = 0; clip->GetInfo(B_REF_TYPE, index, 38502be5353SAxel Dörfler #ifdef B_BEOS_VERSION_DANO 38602be5353SAxel Dörfler (const char **) 38702be5353SAxel Dörfler #endif 38802be5353SAxel Dörfler &refName, &type, &count) == B_OK; index++) { 38902be5353SAxel Dörfler entry_ref ref; 39002be5353SAxel Dörfler if (clip->FindRef(refName, &ref) != B_OK) 39102be5353SAxel Dörfler continue; 39202be5353SAxel Dörfler 39302be5353SAxel Dörfler // If the entry_ref's directory has changed, send previous notification 39402be5353SAxel Dörfler // (if any), and start new one for the new directory 39502be5353SAxel Dörfler if (updateNodeRef.device != ref.device 39602be5353SAxel Dörfler || updateNodeRef.node != ref.directory) { 39702be5353SAxel Dörfler if (updateMessage != NULL) { 39802be5353SAxel Dörfler tracker.SendMessage(updateMessage); 39902be5353SAxel Dörfler delete updateMessage; 40002be5353SAxel Dörfler } 40102be5353SAxel Dörfler 40202be5353SAxel Dörfler updateNodeRef.device = ref.device; 40302be5353SAxel Dörfler updateNodeRef.node = ref.directory; 40402be5353SAxel Dörfler 40502be5353SAxel Dörfler updateMessage = new BMessage(kFSClipboardChanges); 40602be5353SAxel Dörfler updateMessage->AddInt32("device", updateNodeRef.device); 40702be5353SAxel Dörfler updateMessage->AddInt64("directory", updateNodeRef.node); 40802be5353SAxel Dörfler } 40902be5353SAxel Dörfler 41002be5353SAxel Dörfler // we need this data later on 41102be5353SAxel Dörfler MakeModeNameFromRefName(modeName, refName); 41202be5353SAxel Dörfler if (!linksMode && clip->FindInt32(modeName, (int32 *)&moveMode) != B_OK) 41302be5353SAxel Dörfler continue; 41402be5353SAxel Dörfler 41502be5353SAxel Dörfler BEntry entry(&ref); 41602be5353SAxel Dörfler 41702be5353SAxel Dörfler uint32 newMoveMode = 0; 41802be5353SAxel Dörfler bool sameDirectory = destNodeRef->device == ref.device && destNodeRef->node == ref.directory; 41902be5353SAxel Dörfler 42002be5353SAxel Dörfler if (!entry.Exists()) { 42102be5353SAxel Dörfler // The entry doesn't exist anymore, so we'll remove 42202be5353SAxel Dörfler // that entry from the clipboard as well 42302be5353SAxel Dörfler clip->RemoveName(refName); 42402be5353SAxel Dörfler clip->RemoveName(modeName); 42502be5353SAxel Dörfler 42602be5353SAxel Dörfler newMoveMode = kDelete; 42702be5353SAxel Dörfler } else { 42802be5353SAxel Dörfler // the entry does exist, so lets see what we will 42902be5353SAxel Dörfler // do with it 43002be5353SAxel Dörfler if (!sameDirectory) { 43102be5353SAxel Dörfler if (linksMode || moveMode == kMoveSelectionTo) { 43202be5353SAxel Dörfler // the linksMode uses the moveList as well 43302be5353SAxel Dörfler moveList->AddItem(new entry_ref(ref)); 43402be5353SAxel Dörfler } else if (moveMode == kCopySelectionTo) 43502be5353SAxel Dörfler copyList->AddItem(new entry_ref(ref)); 43602be5353SAxel Dörfler } 43702be5353SAxel Dörfler 43802be5353SAxel Dörfler // if the entry should have been removed from its directory, 43902be5353SAxel Dörfler // we want to copy that entry next time, no matter if the 44002be5353SAxel Dörfler // items don't have to be moved at all (source == target) 44102be5353SAxel Dörfler if (moveMode == kMoveSelectionTo) 44202be5353SAxel Dörfler newMoveMode = kCopySelectionTo; 44302be5353SAxel Dörfler } 44402be5353SAxel Dörfler 44502be5353SAxel Dörfler // add the change to the update message (if necessary) 44602be5353SAxel Dörfler if (newMoveMode) { 44702be5353SAxel Dörfler clip->ReplaceInt32(modeName, kCopySelectionTo); 44802be5353SAxel Dörfler 44902be5353SAxel Dörfler TClipboardNodeRef clipNode; 45002be5353SAxel Dörfler MakeNodeFromName(&clipNode.node, modeName); 45102be5353SAxel Dörfler clipNode.moveMode = kDelete; 45202be5353SAxel Dörfler updateMessage->AddData("tcnode", T_CLIPBOARD_NODE, &clipNode, 45302be5353SAxel Dörfler sizeof(TClipboardNodeRef), true); 45402be5353SAxel Dörfler } 45502be5353SAxel Dörfler } 45602be5353SAxel Dörfler be_clipboard->Commit(); 45702be5353SAxel Dörfler 45802be5353SAxel Dörfler // send notification for the last directory 45902be5353SAxel Dörfler if (updateMessage != NULL) { 46002be5353SAxel Dörfler tracker.SendMessage(updateMessage); 46102be5353SAxel Dörfler delete updateMessage; 46202be5353SAxel Dörfler } 46302be5353SAxel Dörfler } 46402be5353SAxel Dörfler be_clipboard->Unlock(); 46502be5353SAxel Dörfler } 46602be5353SAxel Dörfler 46702be5353SAxel Dörfler bool okToMove = true; 46802be5353SAxel Dörfler 46902be5353SAxel Dörfler // can't copy/paste to root('/') directory 47002be5353SAxel Dörfler if (model->IsRoot()) { 471019f90e6SJonas Sundström BAlert *alert = new BAlert("", kNoCopyToRootStr, "Cancel", 472019f90e6SJonas Sundström NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT); 473019f90e6SJonas Sundström alert->SetShortcut(0, B_ESCAPE); 474019f90e6SJonas Sundström alert->Go(); 47502be5353SAxel Dörfler okToMove = false; 47602be5353SAxel Dörfler } 47702be5353SAxel Dörfler 47802be5353SAxel Dörfler BEntry entry; 47902be5353SAxel Dörfler model->GetEntry(&entry); 48002be5353SAxel Dörfler 48102be5353SAxel Dörfler // can't copy items into the trash 482d9626569SRene Gollent if (copyList->CountItems() > 0 && model->IsTrash()) { 483019f90e6SJonas Sundström BAlert *alert = new BAlert("", kNoCopyToTrashStr, "Cancel", 484019f90e6SJonas Sundström NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT); 485019f90e6SJonas Sundström alert->SetShortcut(0, B_ESCAPE); 486019f90e6SJonas Sundström alert->Go(); 48702be5353SAxel Dörfler okToMove = false; 48802be5353SAxel Dörfler } 48902be5353SAxel Dörfler 49002be5353SAxel Dörfler if (!okToMove) { 49102be5353SAxel Dörfler // there was some problem with our target, so we bail out here 49202be5353SAxel Dörfler delete moveList; 49302be5353SAxel Dörfler delete copyList; 49402be5353SAxel Dörfler return false; 49502be5353SAxel Dörfler } 49602be5353SAxel Dörfler 49702be5353SAxel Dörfler // asynchronous calls take over ownership of the objects passed to it 49802be5353SAxel Dörfler if (moveList->CountItems() > 0) 49902be5353SAxel Dörfler FSMoveToFolder(moveList, new BEntry(entry), linksMode ? linksMode : kMoveSelectionTo); 50002be5353SAxel Dörfler else 50102be5353SAxel Dörfler delete moveList; 50202be5353SAxel Dörfler 50302be5353SAxel Dörfler if (copyList->CountItems() > 0) 50402be5353SAxel Dörfler FSMoveToFolder(copyList, new BEntry(entry), kCopySelectionTo); 50502be5353SAxel Dörfler else 50602be5353SAxel Dörfler delete copyList; 50702be5353SAxel Dörfler 50802be5353SAxel Dörfler return true; 50902be5353SAxel Dörfler } 51002be5353SAxel Dörfler 51102be5353SAxel Dörfler 51202be5353SAxel Dörfler /** Seek node in clipboard, if found return it's moveMode 51302be5353SAxel Dörfler * else return 0 51402be5353SAxel Dörfler */ 51502be5353SAxel Dörfler 51602be5353SAxel Dörfler uint32 51795da0645SRene Gollent FSClipboardFindNodeMode(Model *model, bool autoLock, bool updateRefIfNeeded) 51802be5353SAxel Dörfler { 51902be5353SAxel Dörfler int32 moveMode = 0; 52095da0645SRene Gollent if (autoLock) { 52195da0645SRene Gollent if (!be_clipboard->Lock()) 52295da0645SRene Gollent return 0; 52395da0645SRene Gollent } 52402be5353SAxel Dörfler bool remove = false; 52502be5353SAxel Dörfler bool change = false; 52602be5353SAxel Dörfler 52702be5353SAxel Dörfler BMessage *clip = be_clipboard->Data(); 52802be5353SAxel Dörfler if (clip != NULL) { 52902be5353SAxel Dörfler const node_ref *node = model->NodeRef(); 53002be5353SAxel Dörfler char modeName[64]; 53102be5353SAxel Dörfler MakeModeName(modeName, node); 53202be5353SAxel Dörfler if ((clip->FindInt32(modeName, &moveMode) == B_OK)) { 53302be5353SAxel Dörfler const entry_ref *ref = model->EntryRef(); 53402be5353SAxel Dörfler entry_ref clipref; 53502be5353SAxel Dörfler char refName[64]; 53602be5353SAxel Dörfler MakeRefName(refName, node); 53702be5353SAxel Dörfler if ((clip->FindRef(refName, &clipref) == B_OK)) { 53802be5353SAxel Dörfler if (clipref != *ref) { 53902be5353SAxel Dörfler if (updateRefIfNeeded) { 54002be5353SAxel Dörfler clip->ReplaceRef(refName, ref); 54102be5353SAxel Dörfler change = true; 54202be5353SAxel Dörfler } else { 54302be5353SAxel Dörfler clip->RemoveName(refName); 54402be5353SAxel Dörfler clip->RemoveName(modeName); 54502be5353SAxel Dörfler change = true; 54602be5353SAxel Dörfler remove = true; 54702be5353SAxel Dörfler moveMode = 0; 54802be5353SAxel Dörfler } 54902be5353SAxel Dörfler } 55002be5353SAxel Dörfler } else { 55102be5353SAxel Dörfler clip->RemoveName(modeName); 55202be5353SAxel Dörfler change = true; 55302be5353SAxel Dörfler remove = true; 55402be5353SAxel Dörfler moveMode = 0; 55502be5353SAxel Dörfler } 55602be5353SAxel Dörfler } 55702be5353SAxel Dörfler } 55802be5353SAxel Dörfler if (change) 55902be5353SAxel Dörfler be_clipboard->Commit(); 56002be5353SAxel Dörfler 56195da0645SRene Gollent if (autoLock) 56202be5353SAxel Dörfler be_clipboard->Unlock(); 56302be5353SAxel Dörfler 56402be5353SAxel Dörfler if (remove) 56502be5353SAxel Dörfler FSClipboardRemove(model); 56602be5353SAxel Dörfler 56702be5353SAxel Dörfler return (uint32)moveMode; 56802be5353SAxel Dörfler } 56902be5353SAxel Dörfler 57002be5353SAxel Dörfler 57102be5353SAxel Dörfler void 57202be5353SAxel Dörfler FSClipboardRemove(Model *model) 57302be5353SAxel Dörfler { 57402be5353SAxel Dörfler BMessenger messenger(kTrackerSignature); 57502be5353SAxel Dörfler if (messenger.IsValid()) { 57602be5353SAxel Dörfler BMessage *report = new BMessage(kFSClipboardChanges); 57702be5353SAxel Dörfler TClipboardNodeRef tcnode; 57802be5353SAxel Dörfler tcnode.node = *model->NodeRef(); 57902be5353SAxel Dörfler tcnode.moveMode = kDelete; 58002be5353SAxel Dörfler const entry_ref *ref = model->EntryRef(); 58102be5353SAxel Dörfler report->AddInt32("device", ref->device); 58202be5353SAxel Dörfler report->AddInt64("directory", ref->directory); 58302be5353SAxel Dörfler report->AddBool("clearClipboard", false); 58402be5353SAxel Dörfler report->AddData("tcnode", T_CLIPBOARD_NODE, &tcnode, sizeof(tcnode), true); 58502be5353SAxel Dörfler messenger.SendMessage(report); 58602be5353SAxel Dörfler delete report; 58702be5353SAxel Dörfler } 58802be5353SAxel Dörfler } 58902be5353SAxel Dörfler 59002be5353SAxel Dörfler 59102be5353SAxel Dörfler // #pragma mark - 59202be5353SAxel Dörfler 59302be5353SAxel Dörfler 59402be5353SAxel Dörfler BClipboardRefsWatcher::BClipboardRefsWatcher() 59502be5353SAxel Dörfler : BLooper("ClipboardRefsWatcher", B_LOW_PRIORITY, 4096), 59602be5353SAxel Dörfler fNotifyList(10, false) 59702be5353SAxel Dörfler { 59802be5353SAxel Dörfler watch_node(NULL, B_WATCH_MOUNT, this); 59902be5353SAxel Dörfler fRefsInClipboard = FSClipboardHasRefs(); 60002be5353SAxel Dörfler be_clipboard->StartWatching(this); 60102be5353SAxel Dörfler } 60202be5353SAxel Dörfler 60302be5353SAxel Dörfler 60402be5353SAxel Dörfler BClipboardRefsWatcher::~BClipboardRefsWatcher() 60502be5353SAxel Dörfler { 60602be5353SAxel Dörfler stop_watching(this); 60702be5353SAxel Dörfler be_clipboard->StopWatching(this); 60802be5353SAxel Dörfler } 60902be5353SAxel Dörfler 61002be5353SAxel Dörfler 61102be5353SAxel Dörfler void 61202be5353SAxel Dörfler BClipboardRefsWatcher::AddToNotifyList(BMessenger target) 61302be5353SAxel Dörfler { 61402be5353SAxel Dörfler if (Lock()) { 61502be5353SAxel Dörfler // add the messenger if it's not already in the list 61602be5353SAxel Dörfler // ToDo: why do we have to care about that? 61702be5353SAxel Dörfler BMessenger *messenger; 61802be5353SAxel Dörfler bool found = false; 61902be5353SAxel Dörfler 62002be5353SAxel Dörfler for (int32 index = 0;(messenger = fNotifyList.ItemAt(index)) != NULL; index++) { 62102be5353SAxel Dörfler if (*messenger == target) { 62202be5353SAxel Dörfler found = true; 62302be5353SAxel Dörfler break; 62402be5353SAxel Dörfler } 62502be5353SAxel Dörfler } 62602be5353SAxel Dörfler if (!found) 62702be5353SAxel Dörfler fNotifyList.AddItem(new BMessenger(target)); 62802be5353SAxel Dörfler 62902be5353SAxel Dörfler Unlock(); 63002be5353SAxel Dörfler } 63102be5353SAxel Dörfler } 63202be5353SAxel Dörfler 63302be5353SAxel Dörfler 63402be5353SAxel Dörfler void 63502be5353SAxel Dörfler BClipboardRefsWatcher::RemoveFromNotifyList(BMessenger target) 63602be5353SAxel Dörfler { 63702be5353SAxel Dörfler if (Lock()) { 63802be5353SAxel Dörfler BMessenger *messenger; 63902be5353SAxel Dörfler 64002be5353SAxel Dörfler for (int32 index = 0;(messenger = fNotifyList.ItemAt(index)) != NULL; index++) { 64102be5353SAxel Dörfler if (*messenger == target) { 64202be5353SAxel Dörfler delete fNotifyList.RemoveItemAt(index); 64302be5353SAxel Dörfler break; 64402be5353SAxel Dörfler } 64502be5353SAxel Dörfler } 64602be5353SAxel Dörfler Unlock(); 64702be5353SAxel Dörfler } 64802be5353SAxel Dörfler } 64902be5353SAxel Dörfler 65002be5353SAxel Dörfler 65102be5353SAxel Dörfler void 65202be5353SAxel Dörfler BClipboardRefsWatcher::AddNode(const node_ref *node) 65302be5353SAxel Dörfler { 65402be5353SAxel Dörfler TTracker::WatchNode(node, B_WATCH_NAME, this); 65502be5353SAxel Dörfler fRefsInClipboard = true; 65602be5353SAxel Dörfler } 65702be5353SAxel Dörfler 65802be5353SAxel Dörfler 65902be5353SAxel Dörfler void 66002be5353SAxel Dörfler BClipboardRefsWatcher::RemoveNode(node_ref *node, bool removeFromClipboard) 66102be5353SAxel Dörfler { 66202be5353SAxel Dörfler watch_node(node, B_STOP_WATCHING, this); 66302be5353SAxel Dörfler 66402be5353SAxel Dörfler if (!removeFromClipboard) 66502be5353SAxel Dörfler return; 66602be5353SAxel Dörfler 66702be5353SAxel Dörfler if (be_clipboard->Lock()) { 66802be5353SAxel Dörfler BMessage *clip = be_clipboard->Data(); 66902be5353SAxel Dörfler if (clip != NULL) { 67002be5353SAxel Dörfler char name[64]; 67102be5353SAxel Dörfler MakeRefName(name, node); 67202be5353SAxel Dörfler clip->RemoveName(name); 67302be5353SAxel Dörfler MakeModeName(name); 67402be5353SAxel Dörfler clip->RemoveName(name); 67502be5353SAxel Dörfler 67602be5353SAxel Dörfler be_clipboard->Commit(); 67702be5353SAxel Dörfler } 67802be5353SAxel Dörfler be_clipboard->Unlock(); 67902be5353SAxel Dörfler } 68002be5353SAxel Dörfler } 68102be5353SAxel Dörfler 68202be5353SAxel Dörfler 68302be5353SAxel Dörfler void 68402be5353SAxel Dörfler BClipboardRefsWatcher::RemoveNodesByDevice(dev_t device) 68502be5353SAxel Dörfler { 68602be5353SAxel Dörfler if (!be_clipboard->Lock()) 68702be5353SAxel Dörfler return; 68802be5353SAxel Dörfler 68902be5353SAxel Dörfler BMessage *clip = be_clipboard->Data(); 69002be5353SAxel Dörfler if (clip != NULL) { 69102be5353SAxel Dörfler char deviceName[6]; 69202be5353SAxel Dörfler sprintf(deviceName, "r%ld_", device); 69302be5353SAxel Dörfler 69402be5353SAxel Dörfler int32 index = 0; 69502be5353SAxel Dörfler char *refName; 69602be5353SAxel Dörfler type_code type; 69702be5353SAxel Dörfler int32 count; 69802be5353SAxel Dörfler while (clip->GetInfo(B_REF_TYPE, index, 69902be5353SAxel Dörfler #ifdef B_BEOS_VERSION_DANO 70002be5353SAxel Dörfler (const char **) 70102be5353SAxel Dörfler #endif 70202be5353SAxel Dörfler &refName, &type, &count) == B_OK) { 70302be5353SAxel Dörfler if (!strncmp(deviceName, refName, strlen(deviceName))) { 70402be5353SAxel Dörfler clip->RemoveName(refName); 70502be5353SAxel Dörfler MakeModeName(refName); 70602be5353SAxel Dörfler clip->RemoveName(refName); 70702be5353SAxel Dörfler 70802be5353SAxel Dörfler node_ref node; 70902be5353SAxel Dörfler MakeNodeFromName(&node, refName); 71002be5353SAxel Dörfler watch_node(&node, B_STOP_WATCHING, this); 71102be5353SAxel Dörfler } 71202be5353SAxel Dörfler index++; 71302be5353SAxel Dörfler } 71402be5353SAxel Dörfler be_clipboard->Commit(); 71502be5353SAxel Dörfler } 71602be5353SAxel Dörfler be_clipboard->Unlock(); 71702be5353SAxel Dörfler } 71802be5353SAxel Dörfler 71902be5353SAxel Dörfler 72002be5353SAxel Dörfler void 72102be5353SAxel Dörfler BClipboardRefsWatcher::UpdateNode(node_ref *node, entry_ref *ref) 72202be5353SAxel Dörfler { 72302be5353SAxel Dörfler if (!be_clipboard->Lock()) 72402be5353SAxel Dörfler return; 72502be5353SAxel Dörfler 72602be5353SAxel Dörfler BMessage *clip = be_clipboard->Data(); 72702be5353SAxel Dörfler if (clip != NULL) { 72802be5353SAxel Dörfler char name[64]; 72902be5353SAxel Dörfler MakeRefName(name, node); 73002be5353SAxel Dörfler if ((clip->ReplaceRef(name, ref)) != B_OK) { 73102be5353SAxel Dörfler clip->RemoveName(name); 73202be5353SAxel Dörfler MakeModeName(name); 73302be5353SAxel Dörfler clip->RemoveName(name); 73402be5353SAxel Dörfler 73502be5353SAxel Dörfler RemoveNode(node); 73602be5353SAxel Dörfler } 73702be5353SAxel Dörfler be_clipboard->Commit(); 73802be5353SAxel Dörfler } 73902be5353SAxel Dörfler be_clipboard->Unlock(); 74002be5353SAxel Dörfler } 74102be5353SAxel Dörfler 74202be5353SAxel Dörfler 74302be5353SAxel Dörfler void 74402be5353SAxel Dörfler BClipboardRefsWatcher::Clear() 74502be5353SAxel Dörfler { 74602be5353SAxel Dörfler stop_watching(this); 74702be5353SAxel Dörfler watch_node(NULL, B_WATCH_MOUNT, this); 74802be5353SAxel Dörfler 74902be5353SAxel Dörfler BMessage message(kFSClipboardChanges); 75002be5353SAxel Dörfler message.AddBool("clearClipboard", true); 75102be5353SAxel Dörfler if (Lock()) { 75202be5353SAxel Dörfler int32 items = fNotifyList.CountItems(); 75302be5353SAxel Dörfler for (int32 i = 0;i < items;i++) { 75402be5353SAxel Dörfler fNotifyList.ItemAt(i)->SendMessage(&message); 75502be5353SAxel Dörfler } 75602be5353SAxel Dörfler Unlock(); 75702be5353SAxel Dörfler } 75802be5353SAxel Dörfler } 75902be5353SAxel Dörfler 76002be5353SAxel Dörfler /* 76102be5353SAxel Dörfler void 76202be5353SAxel Dörfler BClipboardRefsWatcher::UpdatePoseViews(bool clearClipboard, const node_ref *node) 76302be5353SAxel Dörfler { 76402be5353SAxel Dörfler BMessage message(kFSClipboardChanges); 76502be5353SAxel Dörfler message.AddInt32("device", node->device); 76602be5353SAxel Dörfler message.AddInt64("directory", node->node); 76702be5353SAxel Dörfler message.AddBool("clearClipboard", clearClipboard); 76802be5353SAxel Dörfler 76902be5353SAxel Dörfler if (Lock()) { 77002be5353SAxel Dörfler int32 items = fNotifyList.CountItems(); 77102be5353SAxel Dörfler for (int32 i = 0;i < items;i++) { 77202be5353SAxel Dörfler fNotifyList.ItemAt(i)->SendMessage(&message); 77302be5353SAxel Dörfler } 77402be5353SAxel Dörfler Unlock(); 77502be5353SAxel Dörfler } 77602be5353SAxel Dörfler } 77702be5353SAxel Dörfler */ 77802be5353SAxel Dörfler 77902be5353SAxel Dörfler void 78002be5353SAxel Dörfler BClipboardRefsWatcher::UpdatePoseViews(BMessage *reportMessage) 78102be5353SAxel Dörfler { 78202be5353SAxel Dörfler if (Lock()) { 78302be5353SAxel Dörfler // check if it was cleared, if so clear watching 78402be5353SAxel Dörfler bool clearClipboard = false; 78502be5353SAxel Dörfler if (reportMessage->FindBool("clearClipboard", &clearClipboard) == B_OK 78602be5353SAxel Dörfler && clearClipboard) { 78702be5353SAxel Dörfler stop_watching(this); 78802be5353SAxel Dörfler watch_node(NULL, B_WATCH_MOUNT, this); 78902be5353SAxel Dörfler } 79002be5353SAxel Dörfler 79102be5353SAxel Dörfler // loop through reported node_ref's movemodes: 79202be5353SAxel Dörfler // move or copy: start watching node_ref 79302be5353SAxel Dörfler // remove: stop watching node_ref 79402be5353SAxel Dörfler int32 index = 0; 79502be5353SAxel Dörfler TClipboardNodeRef *tcnode = NULL; 79602be5353SAxel Dörfler ssize_t size; 79702be5353SAxel Dörfler while (reportMessage->FindData("tcnode", T_CLIPBOARD_NODE, index, (const void**)&tcnode, &size) == B_OK) { 79802be5353SAxel Dörfler if (tcnode->moveMode == kDelete) { 79902be5353SAxel Dörfler watch_node(&tcnode->node, B_STOP_WATCHING, this); 80002be5353SAxel Dörfler } else { 80102be5353SAxel Dörfler watch_node(&tcnode->node, B_STOP_WATCHING, this); 80202be5353SAxel Dörfler TTracker::WatchNode(&tcnode->node, B_WATCH_NAME, this); 80302be5353SAxel Dörfler fRefsInClipboard = true; 80402be5353SAxel Dörfler } 80502be5353SAxel Dörfler index++; 80602be5353SAxel Dörfler } 80702be5353SAxel Dörfler 80802be5353SAxel Dörfler // send report 80902be5353SAxel Dörfler int32 items = fNotifyList.CountItems(); 81002be5353SAxel Dörfler for (int32 i = 0;i < items;i++) { 81102be5353SAxel Dörfler fNotifyList.ItemAt(i)->SendMessage(reportMessage); 81202be5353SAxel Dörfler } 81302be5353SAxel Dörfler Unlock(); 81402be5353SAxel Dörfler } 81502be5353SAxel Dörfler } 81602be5353SAxel Dörfler 81702be5353SAxel Dörfler 81802be5353SAxel Dörfler void 81902be5353SAxel Dörfler BClipboardRefsWatcher::MessageReceived(BMessage *message) 82002be5353SAxel Dörfler { 82102be5353SAxel Dörfler if (message->what == B_CLIPBOARD_CHANGED && fRefsInClipboard) { 82202be5353SAxel Dörfler if (!(fRefsInClipboard = FSClipboardHasRefs())) 82302be5353SAxel Dörfler Clear(); 82402be5353SAxel Dörfler return; 82502be5353SAxel Dörfler } else if (message->what != B_NODE_MONITOR) { 82602be5353SAxel Dörfler _inherited::MessageReceived(message); 82702be5353SAxel Dörfler return; 82802be5353SAxel Dörfler } 82902be5353SAxel Dörfler 83002be5353SAxel Dörfler switch (message->FindInt32("opcode")) { 83102be5353SAxel Dörfler case B_ENTRY_MOVED: 83202be5353SAxel Dörfler { 83302be5353SAxel Dörfler ino_t toDir; 83402be5353SAxel Dörfler ino_t fromDir; 83502be5353SAxel Dörfler node_ref node; 83602be5353SAxel Dörfler const char *name = NULL; 83702be5353SAxel Dörfler message->FindInt64("from directory", &fromDir); 83802be5353SAxel Dörfler message->FindInt64("to directory", &toDir); 83902be5353SAxel Dörfler message->FindInt64("node", &node.node); 84002be5353SAxel Dörfler message->FindInt32("device", &node.device); 84102be5353SAxel Dörfler message->FindString("name", &name); 84202be5353SAxel Dörfler entry_ref ref(node.device, toDir, name); 84302be5353SAxel Dörfler UpdateNode(&node, &ref); 84402be5353SAxel Dörfler break; 84502be5353SAxel Dörfler } 84602be5353SAxel Dörfler 84702be5353SAxel Dörfler case B_DEVICE_UNMOUNTED: 84802be5353SAxel Dörfler { 84902be5353SAxel Dörfler dev_t device; 85002be5353SAxel Dörfler message->FindInt32("device", &device); 85102be5353SAxel Dörfler RemoveNodesByDevice(device); 85202be5353SAxel Dörfler break; 85302be5353SAxel Dörfler } 85402be5353SAxel Dörfler 85502be5353SAxel Dörfler case B_ENTRY_REMOVED: 85602be5353SAxel Dörfler { 85702be5353SAxel Dörfler node_ref node; 85802be5353SAxel Dörfler message->FindInt64("node", &node.node); 85902be5353SAxel Dörfler message->FindInt32("device", &node.device); 86002be5353SAxel Dörfler RemoveNode(&node, true); 86102be5353SAxel Dörfler break; 86202be5353SAxel Dörfler } 86302be5353SAxel Dörfler } 86402be5353SAxel Dörfler } 865