BTRFS: Implement BTree::Path and change _Find.
[haiku.git] / src / apps / showimage / ShowImageApp.cpp
blob5e8feeb15997067eebddde783ddccd9505923df5
1 /*
2 * Copyright 2003-2010, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Fernando Francisco de Oliveira
7 * Michael Wilber
8 * Michael Pfeiffer
9 * Ryan Leavengood
13 #include "ShowImageApp.h"
15 #include <stdio.h>
17 #include <Catalog.h>
18 #include <Clipboard.h>
19 #include <FilePanel.h>
20 #include <Locale.h>
21 #include <Path.h>
22 #include <Screen.h>
23 #include <String.h>
25 #include "ShowImageConstants.h"
26 #include "ShowImageWindow.h"
27 #include "ToolBarIcons.h"
30 const char* kApplicationSignature = "application/x-vnd.Haiku-ShowImage";
31 const int32 kWindowsToIgnore = 1;
32 // ignore the always open file panel
35 ShowImageApp::ShowImageApp()
37 BApplication(kApplicationSignature),
38 fOpenPanel(new BFilePanel(B_OPEN_PANEL)),
39 fPulseStarted(false),
40 fLastWindowFrame(BRect(30, 30, 430, 330))
42 B_TRANSLATE_MARK_SYSTEM_NAME_VOID("ShowImage");
43 _UpdateLastWindowFrame();
44 // BBitmap can be created after there is a BApplication instance.
45 init_tool_bar_icons();
49 ShowImageApp::~ShowImageApp()
51 // BBitmap must be deleted while there is still a BApplication instance.
52 uninit_tool_bar_icons();
56 void
57 ShowImageApp::ArgvReceived(int32 argc, char **argv)
59 BMessage message;
60 bool hasRefs = false;
62 // get current working directory
63 const char* cwd;
64 if (CurrentMessage() == NULL
65 || CurrentMessage()->FindString("cwd", &cwd) != B_OK)
66 cwd = "";
68 for (int32 i = 1; i < argc; i++) {
69 BPath path;
70 if (argv[i][0] == '/') {
71 // absolute path
72 path.SetTo(argv[i]);
73 } else {
74 // relative path
75 path.SetTo(cwd);
76 path.Append(argv[i]);
79 entry_ref ref;
80 status_t err = get_ref_for_path(path.Path(), &ref);
81 if (err == B_OK) {
82 message.AddRef("refs", &ref);
83 hasRefs = true;
87 if (hasRefs)
88 RefsReceived(&message);
92 void
93 ShowImageApp::ReadyToRun()
95 if (CountWindows() == kWindowsToIgnore)
96 fOpenPanel->Show();
97 else {
98 // If image windows are already open
99 // (paths supplied on the command line)
100 // start checking the number of open windows
101 _StartPulse();
104 be_clipboard->StartWatching(be_app_messenger);
105 // tell the clipboard to notify this app when its contents change
109 void
110 ShowImageApp::MessageReceived(BMessage* message)
112 switch (message->what) {
113 case MSG_FILE_OPEN:
114 fOpenPanel->Show();
115 break;
117 case B_CANCEL:
118 // File open panel was closed,
119 // start checking count of open windows
120 _StartPulse();
121 break;
123 case B_CLIPBOARD_CHANGED:
124 _CheckClipboard();
125 break;
127 case MSG_WINDOW_HAS_QUIT:
128 // Make sure that new windows open with the location/size of the
129 // last closed window.
130 _UpdateLastWindowFrame();
131 break;
133 default:
134 BApplication::MessageReceived(message);
135 break;
140 void
141 ShowImageApp::Pulse()
143 // Bug: The BFilePanel is automatically closed if the volume that
144 // is displayed is unmounted.
145 if (!IsLaunching() && CountWindows() <= kWindowsToIgnore) {
146 // If the application is not launching and
147 // all windows are closed except for the file open panel,
148 // quit the application
149 PostMessage(B_QUIT_REQUESTED);
154 void
155 ShowImageApp::RefsReceived(BMessage* message)
157 // If a tracker window opened me, get a messenger from it.
158 BMessenger trackerMessenger;
159 if (message->HasMessenger("TrackerViewToken"))
160 message->FindMessenger("TrackerViewToken", &trackerMessenger);
162 entry_ref ref;
163 for (int32 i = 0; message->FindRef("refs", i, &ref) == B_OK; i++)
164 _Open(ref, trackerMessenger);
168 bool
169 ShowImageApp::QuitRequested()
171 // Give the windows a chance to prompt the user if there are changes
172 bool result = BApplication::QuitRequested();
173 if (result) {
174 be_clipboard->StopWatching(be_app_messenger);
175 // tell clipboard we don't want anymore notification
177 DefaultCache().Stop();
179 return result;
183 void
184 ShowImageApp::_StartPulse()
186 if (!fPulseStarted) {
187 // Tell the app to begin checking
188 // for the number of open windows
189 fPulseStarted = true;
190 SetPulseRate(250000);
191 // Set pulse to every 1/4 second
196 void
197 ShowImageApp::_Open(const entry_ref& ref, const BMessenger& trackerMessenger)
199 fLastWindowFrame.OffsetBy(20, 20);
200 if (!BScreen(B_MAIN_SCREEN_ID).Frame().Contains(fLastWindowFrame))
201 fLastWindowFrame.OffsetTo(50, 50);
203 new ShowImageWindow(fLastWindowFrame, ref, trackerMessenger);
207 void
208 ShowImageApp::_BroadcastToWindows(BMessage* message)
210 const int32 count = CountWindows();
211 for (int32 i = 0; i < count; i++) {
212 // BMessenger checks for us if BWindow is still a valid object
213 BMessenger messenger(WindowAt(i));
214 messenger.SendMessage(message);
219 void
220 ShowImageApp::_CheckClipboard()
222 // Determines if the contents of the clipboard contain
223 // data that is useful to this application.
224 // After checking the clipboard, a message is sent to
225 // all windows indicating that the clipboard has changed
226 // and whether or not the clipboard contains useful data.
227 bool dataAvailable = false;
229 if (be_clipboard->Lock()) {
230 BMessage* clip = be_clipboard->Data();
231 if (clip != NULL) {
232 dataAvailable = clip->HasMessage("image/bitmap")
233 || clip->HasMessage("image/x-be-bitmap");
236 be_clipboard->Unlock();
239 BMessage msg(B_CLIPBOARD_CHANGED);
240 msg.AddBool("data_available", dataAvailable);
241 _BroadcastToWindows(&msg);
245 void
246 ShowImageApp::_UpdateLastWindowFrame()
248 fLastWindowFrame = fSettings.GetRect("WindowFrame", fLastWindowFrame);
249 // Compensate the offset which we always add to new windows.
250 fLastWindowFrame.OffsetBy(-20, -20);
254 // #pragma mark -
258 main(int, char**)
260 ShowImageApp app;
261 app.Run();
262 return 0;