diff --git a/src/apps/showimage/ShowImageApp.cpp b/src/apps/showimage/ShowImageApp.cpp index d030d289cd..5509c8eaea 100644 --- a/src/apps/showimage/ShowImageApp.cpp +++ b/src/apps/showimage/ShowImageApp.cpp @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include "ShowImageConstants.h" #include "ShowImageApp.h" @@ -68,6 +70,9 @@ ShowImageApp::ReadyToRun() // (paths supplied on the command line) // start checking the number of open windows StartPulse(); + + be_clipboard->StartWatching(be_app_messenger); + // tell the clipboard to notify this app when its contents change } void @@ -131,6 +136,10 @@ ShowImageApp::MessageReceived(BMessage *pmsg) case MSG_UPDATE_RECENT_DOCUMENTS: BroadcastToWindows(MSG_UPDATE_RECENT_DOCUMENTS); break; + + case B_CLIPBOARD_CHANGED: + CheckClipboard(); + break; default: BApplication::MessageReceived(pmsg); @@ -170,3 +179,52 @@ ShowImageApp::BroadcastToWindows(uint32 what) msgr.SendMessage(what); } } + +void +ShowImageApp::BroadcastToWindows(BMessage *pmsg) +{ + const int32 n = CountWindows(); + for (int32 i = 0; i < n ; i ++) { + // BMessenger checks for us if BWindow is still a valid object + BMessenger msgr(WindowAt(i)); + msgr.SendMessage(pmsg); + } +} + +void +ShowImageApp::CheckClipboard() +{ + // Determines if the contents of the clipboard contain + // data that is useful to this application. + // After checking the clipboard, a message is sent to + // all windows indicating that the clipboard has changed + // and whether or not the clipboard contains useful data. + bool bdata = false; + + if (be_clipboard->Lock()) { + BMessage *pclip; + if ((pclip = be_clipboard->Data()) != NULL) { + BString strClass; + if (pclip->FindString("class", &strClass) == B_OK) { + if (strClass == "BBitmap") + bdata = true; + } + } + + be_clipboard->Unlock(); + } + + BMessage msg(MSG_CLIPBOARD_CHANGED); + msg.AddBool("data_available", bdata); + BroadcastToWindows(&msg); +} + +void +ShowImageApp::Quit() +{ + be_clipboard->StopWatching(be_app_messenger); + // tell clipboard we don't want anymore notification + + BApplication::Quit(); +} + diff --git a/src/apps/showimage/ShowImageApp.h b/src/apps/showimage/ShowImageApp.h index 986331c37e..597844c075 100644 --- a/src/apps/showimage/ShowImageApp.h +++ b/src/apps/showimage/ShowImageApp.h @@ -42,11 +42,14 @@ public: virtual void ReadyToRun(); virtual void Pulse(); virtual void RefsReceived(BMessage *pmsg); + virtual void Quit(); private: void StartPulse(); void Open(const entry_ref *pref); void BroadcastToWindows(uint32 what); + void BroadcastToWindows(BMessage *pmsg); + void CheckClipboard(); BFilePanel *fpOpenPanel; bool fbPulseStarted; diff --git a/src/apps/showimage/ShowImageConstants.h b/src/apps/showimage/ShowImageConstants.h index 197f4d831a..27ee6b3512 100644 --- a/src/apps/showimage/ShowImageConstants.h +++ b/src/apps/showimage/ShowImageConstants.h @@ -40,6 +40,7 @@ const uint32 MSG_OUTPUT_TYPE = 'BTMN'; const uint32 MSG_SAVE_PANEL = 'mFSP'; const uint32 MSG_CLEAR_SELECT = 'mCSL'; const uint32 MSG_SELECT_ALL = 'mSAL'; +const uint32 MSG_CLIPBOARD_CHANGED = 'mCLP'; const uint32 MSG_DITHER_IMAGE = 'mDIM'; const uint32 MSG_UPDATE_STATUS = 'mUPS'; const uint32 MSG_SELECTION = 'mSEL'; diff --git a/src/apps/showimage/ShowImageWindow.cpp b/src/apps/showimage/ShowImageWindow.cpp index c06223f993..f4c122698e 100644 --- a/src/apps/showimage/ShowImageWindow.cpp +++ b/src/apps/showimage/ShowImageWindow.cpp @@ -128,6 +128,10 @@ ShowImageWindow::ShowImageWindow(const entry_ref *pref) // exit if file could not be opened Quit(); } + + // Tell application object to query the clipboard + // and tell this window if it contains interesting data or not + be_app_messenger.SendMessage(B_CLIPBOARD_CHANGED); } ShowImageWindow::~ShowImageWindow() @@ -535,6 +539,17 @@ ShowImageWindow::MessageReceived(BMessage *pmsg) } break; } + + case MSG_CLIPBOARD_CHANGED: + { + // The app sends this message after it examines + // the clipboard in response to a B_CLIPBOARD_CHANGED + // message + bool bdata; + if (pmsg->FindBool("data_available", &bdata) == B_OK) + EnableMenuItem(fpBar, B_PASTE, bdata); + break; + } case B_UNDO: break;