xref: /haiku/src/apps/showimage/ShowImageApp.cpp (revision d5cd5d63ff0ad395989db6cf4841a64d5b545d1d)
1 /*****************************************************************************/
2 // ShowImageApp
3 // Written by Fernando Francisco de Oliveira, Michael Wilber, Michael Pfeiffer
4 //
5 // ShowImageApp.cpp
6 //
7 //
8 // Copyright (c) 2003 OpenBeOS Project
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 // DEALINGS IN THE SOFTWARE.
27 /*****************************************************************************/
28 
29 #include <stdio.h>
30 #include <Alert.h>
31 #include <FilePanel.h>
32 #include <String.h>
33 #include <Clipboard.h>
34 
35 #include "ShowImageConstants.h"
36 #include "ShowImageApp.h"
37 #include "ShowImageWindow.h"
38 
39 int main(int, char **)
40 {
41 	ShowImageApp theApp;
42 	theApp.Run();
43 	return 0;
44 }
45 
46 #define WINDOWS_TO_IGNORE 1
47 
48 ShowImageApp::ShowImageApp()
49 	: BApplication(APP_SIG)
50 {
51 	fPulseStarted = false;
52 	fOpenPanel = new BFilePanel(B_OPEN_PANEL);
53 }
54 
55 void
56 ShowImageApp::AboutRequested()
57 {
58 	BAlert* pAlert = new BAlert("About ShowImage",
59 		"OBOS ShowImage\n\nby Fernando F. Oliveira, Michael Wilber and Michael Pfeiffer", "OK");
60 	pAlert->Go();
61 }
62 
63 void
64 ShowImageApp::ReadyToRun()
65 {
66 	if (CountWindows() == WINDOWS_TO_IGNORE)
67 		fOpenPanel->Show();
68 	else
69 		// If image windows are already open
70 		// (paths supplied on the command line)
71 		// start checking the number of open windows
72 		StartPulse();
73 
74 	be_clipboard->StartWatching(be_app_messenger);
75 		// tell the clipboard to notify this app when its contents change
76 }
77 
78 void
79 ShowImageApp::StartPulse()
80 {
81 	if (!fPulseStarted) {
82 		// Tell the app to begin checking
83 		// for the number of open windows
84 		fPulseStarted = true;
85 		SetPulseRate(250000);
86 			// Set pulse to every 1/4 second
87 	}
88 }
89 
90 void
91 ShowImageApp::Pulse()
92 {
93 	if (!IsLaunching() && CountWindows() <= WINDOWS_TO_IGNORE)
94 		// If the application is not launching and
95 		// all windows are closed except for the file open panel,
96 		// quit the application
97 		PostMessage(B_QUIT_REQUESTED);
98 }
99 
100 void
101 ShowImageApp::ArgvReceived(int32 argc, char **argv)
102 {
103 	BMessage *pmsg = NULL;
104 	for (int32 i = 1; i < argc; i++) {
105 		entry_ref ref;
106 		status_t err = get_ref_for_path(argv[i], &ref);
107 		if (err == B_OK) {
108 			if (!pmsg) {
109 				pmsg = new BMessage;
110 				pmsg->what = B_REFS_RECEIVED;
111 			}
112 			pmsg->AddRef("refs", &ref);
113 		}
114 	}
115 	if (pmsg)
116 		RefsReceived(pmsg);
117 }
118 
119 void
120 ShowImageApp::MessageReceived(BMessage *pmsg)
121 {
122 	switch (pmsg->what) {
123 		case MSG_FILE_OPEN:
124 			fOpenPanel->Show();
125 			break;
126 
127 		case MSG_WINDOW_QUIT:
128 			break;
129 
130 		case B_CANCEL:
131 			// File open panel was closed,
132 			// start checking count of open windows
133 			StartPulse();
134 			break;
135 
136 		case MSG_UPDATE_RECENT_DOCUMENTS:
137 			BroadcastToWindows(MSG_UPDATE_RECENT_DOCUMENTS);
138 			break;
139 
140 		case B_CLIPBOARD_CHANGED:
141 			CheckClipboard();
142 			break;
143 
144 		default:
145 			BApplication::MessageReceived(pmsg);
146 			break;
147 	}
148 }
149 
150 void
151 ShowImageApp::RefsReceived(BMessage *pmsg)
152 {
153 	uint32 type;
154 	int32 count;
155 	status_t ret = pmsg->GetInfo("refs", &type, &count);
156 	if (ret != B_OK || type != B_REF_TYPE)
157 		return;
158 
159 	entry_ref ref;
160 	for (int32 i = 0; i < count; i++) {
161    		if (pmsg->FindRef("refs", i, &ref) == B_OK)
162    			Open(&ref);
163    	}
164 }
165 
166 void
167 ShowImageApp::Open(const entry_ref *pref)
168 {
169 	new ShowImageWindow(pref);
170 }
171 
172 void
173 ShowImageApp::BroadcastToWindows(uint32 what)
174 {
175 	const int32 n = CountWindows();
176 	for (int32 i = 0; i < n ; i ++) {
177 		// BMessenger checks for us if BWindow is still a valid object
178 		BMessenger msgr(WindowAt(i));
179 		msgr.SendMessage(what);
180 	}
181 }
182 
183 void
184 ShowImageApp::BroadcastToWindows(BMessage *pmsg)
185 {
186 	const int32 n = CountWindows();
187 	for (int32 i = 0; i < n ; i ++) {
188 		// BMessenger checks for us if BWindow is still a valid object
189 		BMessenger msgr(WindowAt(i));
190 		msgr.SendMessage(pmsg);
191 	}
192 }
193 
194 void
195 ShowImageApp::CheckClipboard()
196 {
197 	// Determines if the contents of the clipboard contain
198 	// data that is useful to this application.
199 	// After checking the clipboard, a message is sent to
200 	// all windows indicating that the clipboard has changed
201 	// and whether or not the clipboard contains useful data.
202 	bool bdata = false;
203 
204 	if (be_clipboard->Lock()) {
205 		BMessage *pclip;
206 		if ((pclip = be_clipboard->Data()) != NULL) {
207 			BString strClass;
208 			if (pclip->FindString("class", &strClass) == B_OK) {
209 				if (strClass == "BBitmap")
210 					bdata = true;
211 			}
212 		}
213 
214 		be_clipboard->Unlock();
215 	}
216 
217 	BMessage msg(MSG_CLIPBOARD_CHANGED);
218 	msg.AddBool("data_available", bdata);
219 	BroadcastToWindows(&msg);
220 }
221 
222 void
223 ShowImageApp::Quit()
224 {
225 	be_clipboard->StopWatching(be_app_messenger);
226 		// tell clipboard we don't want anymore notification
227 
228 	BApplication::Quit();
229 }
230 
231