265 lines
5.4 KiB
C++
265 lines
5.4 KiB
C++
/*
|
|
* Copyright 2003-2010, Haiku, Inc. All Rights Reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Fernando Francisco de Oliveira
|
|
* Michael Wilber
|
|
* Michael Pfeiffer
|
|
* Ryan Leavengood
|
|
*/
|
|
|
|
|
|
#include "ShowImageApp.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <Catalog.h>
|
|
#include <Clipboard.h>
|
|
#include <FilePanel.h>
|
|
#include <Locale.h>
|
|
#include <Path.h>
|
|
#include <Screen.h>
|
|
#include <String.h>
|
|
|
|
#include "ShowImageConstants.h"
|
|
#include "ShowImageWindow.h"
|
|
#include "ToolBarIcons.h"
|
|
|
|
|
|
const char* kApplicationSignature = "application/x-vnd.Haiku-ShowImage";
|
|
const int32 kWindowsToIgnore = 1;
|
|
// ignore the always open file panel
|
|
|
|
|
|
ShowImageApp::ShowImageApp()
|
|
:
|
|
BApplication(kApplicationSignature),
|
|
fOpenPanel(new BFilePanel(B_OPEN_PANEL)),
|
|
fPulseStarted(false),
|
|
fLastWindowFrame(BRect(30, 30, 430, 330))
|
|
{
|
|
B_TRANSLATE_MARK_SYSTEM_NAME_VOID("ShowImage");
|
|
_UpdateLastWindowFrame();
|
|
// BBitmap can be created after there is a BApplication instance.
|
|
init_tool_bar_icons();
|
|
}
|
|
|
|
|
|
ShowImageApp::~ShowImageApp()
|
|
{
|
|
// BBitmap must be deleted while there is still a BApplication instance.
|
|
uninit_tool_bar_icons();
|
|
}
|
|
|
|
|
|
void
|
|
ShowImageApp::ArgvReceived(int32 argc, char **argv)
|
|
{
|
|
BMessage message;
|
|
bool hasRefs = false;
|
|
|
|
// get current working directory
|
|
const char* cwd;
|
|
if (CurrentMessage() == NULL
|
|
|| CurrentMessage()->FindString("cwd", &cwd) != B_OK)
|
|
cwd = "";
|
|
|
|
for (int32 i = 1; i < argc; i++) {
|
|
BPath path;
|
|
if (argv[i][0] == '/') {
|
|
// absolute path
|
|
path.SetTo(argv[i]);
|
|
} else {
|
|
// relative path
|
|
path.SetTo(cwd);
|
|
path.Append(argv[i]);
|
|
}
|
|
|
|
entry_ref ref;
|
|
status_t err = get_ref_for_path(path.Path(), &ref);
|
|
if (err == B_OK) {
|
|
message.AddRef("refs", &ref);
|
|
hasRefs = true;
|
|
}
|
|
}
|
|
|
|
if (hasRefs)
|
|
RefsReceived(&message);
|
|
}
|
|
|
|
|
|
void
|
|
ShowImageApp::ReadyToRun()
|
|
{
|
|
if (CountWindows() == kWindowsToIgnore)
|
|
fOpenPanel->Show();
|
|
else {
|
|
// If image windows are already open
|
|
// (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
|
|
ShowImageApp::MessageReceived(BMessage* message)
|
|
{
|
|
switch (message->what) {
|
|
case MSG_FILE_OPEN:
|
|
fOpenPanel->Show();
|
|
break;
|
|
|
|
case B_CANCEL:
|
|
// File open panel was closed,
|
|
// start checking count of open windows
|
|
_StartPulse();
|
|
break;
|
|
|
|
case B_CLIPBOARD_CHANGED:
|
|
_CheckClipboard();
|
|
break;
|
|
|
|
case MSG_WINDOW_HAS_QUIT:
|
|
// Make sure that new windows open with the location/size of the
|
|
// last closed window.
|
|
_UpdateLastWindowFrame();
|
|
break;
|
|
|
|
default:
|
|
BApplication::MessageReceived(message);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
ShowImageApp::Pulse()
|
|
{
|
|
// Bug: The BFilePanel is automatically closed if the volume that
|
|
// is displayed is unmounted.
|
|
if (!IsLaunching() && CountWindows() <= kWindowsToIgnore) {
|
|
// If the application is not launching and
|
|
// all windows are closed except for the file open panel,
|
|
// quit the application
|
|
PostMessage(B_QUIT_REQUESTED);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
ShowImageApp::RefsReceived(BMessage* message)
|
|
{
|
|
// If a tracker window opened me, get a messenger from it.
|
|
BMessenger trackerMessenger;
|
|
if (message->HasMessenger("TrackerViewToken"))
|
|
message->FindMessenger("TrackerViewToken", &trackerMessenger);
|
|
|
|
entry_ref ref;
|
|
for (int32 i = 0; message->FindRef("refs", i, &ref) == B_OK; i++)
|
|
_Open(ref, trackerMessenger);
|
|
}
|
|
|
|
|
|
bool
|
|
ShowImageApp::QuitRequested()
|
|
{
|
|
// Give the windows a chance to prompt the user if there are changes
|
|
bool result = BApplication::QuitRequested();
|
|
if (result) {
|
|
be_clipboard->StopWatching(be_app_messenger);
|
|
// tell clipboard we don't want anymore notification
|
|
}
|
|
DefaultCache().Stop();
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
void
|
|
ShowImageApp::_StartPulse()
|
|
{
|
|
if (!fPulseStarted) {
|
|
// Tell the app to begin checking
|
|
// for the number of open windows
|
|
fPulseStarted = true;
|
|
SetPulseRate(250000);
|
|
// Set pulse to every 1/4 second
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
ShowImageApp::_Open(const entry_ref& ref, const BMessenger& trackerMessenger)
|
|
{
|
|
fLastWindowFrame.OffsetBy(20, 20);
|
|
if (!BScreen(B_MAIN_SCREEN_ID).Frame().Contains(fLastWindowFrame))
|
|
fLastWindowFrame.OffsetTo(50, 50);
|
|
|
|
new ShowImageWindow(fLastWindowFrame, ref, trackerMessenger);
|
|
}
|
|
|
|
|
|
void
|
|
ShowImageApp::_BroadcastToWindows(BMessage* message)
|
|
{
|
|
const int32 count = CountWindows();
|
|
for (int32 i = 0; i < count; i++) {
|
|
// BMessenger checks for us if BWindow is still a valid object
|
|
BMessenger messenger(WindowAt(i));
|
|
messenger.SendMessage(message);
|
|
}
|
|
}
|
|
|
|
|
|
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 dataAvailable = false;
|
|
|
|
if (be_clipboard->Lock()) {
|
|
BMessage* clip = be_clipboard->Data();
|
|
if (clip != NULL) {
|
|
dataAvailable = clip->HasMessage("image/bitmap")
|
|
|| clip->HasMessage("image/x-be-bitmap");
|
|
}
|
|
|
|
be_clipboard->Unlock();
|
|
}
|
|
|
|
BMessage msg(B_CLIPBOARD_CHANGED);
|
|
msg.AddBool("data_available", dataAvailable);
|
|
_BroadcastToWindows(&msg);
|
|
}
|
|
|
|
|
|
void
|
|
ShowImageApp::_UpdateLastWindowFrame()
|
|
{
|
|
fLastWindowFrame = fSettings.GetRect("WindowFrame", fLastWindowFrame);
|
|
// Compensate the offset which we always add to new windows.
|
|
fLastWindowFrame.OffsetBy(-20, -20);
|
|
}
|
|
|
|
|
|
// #pragma mark -
|
|
|
|
|
|
int
|
|
main(int, char**)
|
|
{
|
|
ShowImageApp app;
|
|
app.Run();
|
|
return 0;
|
|
}
|
|
|