* Moved the about alert handling into the application

* Simplified the handling of the first window and removed FirstWindow(),
  we can tell by fPlayerCount.
* Both the above would fix a crash when requesting the about alert with the
  first window already gone. Respectively another player instance opening
  if fFirstWindow was reset to NULL after some recent revision.
* Implemented restoring the current playlist, index and position in the file.
* Devised a more robust way to solve asynchronous seeking. The Controller is
  now notified that a seek request has been handled with a dedicated hook.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34079 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2009-11-16 22:48:19 +00:00
parent 9a7463857a
commit ab18a50229
9 changed files with 295 additions and 148 deletions

View File

@ -106,8 +106,7 @@ Controller::Controller()
fPosition(0),
fDuration(0),
fVideoFrameRate(25.0),
fSeekFrame(-1),
fLastSeekEventTime(LONGLONG_MIN),
fSeekRequested(false),
fGlobalSettingsListener(this),
@ -316,6 +315,8 @@ Controller::SetTo(const PlaylistItemRef& item)
const media_format& audioTrackFormat = fAudioTrackSupplier->Format();
audioFrameRate = audioTrackFormat.u.raw_audio.frame_rate;
audioChannels = audioTrackFormat.u.raw_audio.channel_count;
// if (fVideoTrackSupplier == NULL)
// fVideoFrameRate = audioFrameRate;
}
if (InitCheck() != B_OK) {
@ -659,13 +660,33 @@ Controller::SetPosition(float value)
{
BAutolock _(this);
fSeekFrame = (int32)(Duration() * value);
SetFramePosition(Duration() * value);
}
void
Controller::SetFramePosition(int32 value)
{
printf("Controller::SetFramePosition(%ld)\n", value);
BAutolock _(this);
int32 seekFrame = max_c(0, min_c(Duration(), value));
int32 currentFrame = CurrentFrame();
if (fSeekFrame != currentFrame) {
SetCurrentFrame(fSeekFrame);
fLastSeekEventTime = system_time();
} else
fSeekFrame = -1;
if (seekFrame != currentFrame) {
printf(" adjusted seek frame\n");
fSeekFrame = seekFrame;
fSeekRequested = true;
SetCurrentFrame(seekFrame);
}
}
void
Controller::SetTimePosition(bigtime_t value)
{
BAutolock _(this);
SetPosition((float)value / TimeDuration());
}
@ -1009,11 +1030,11 @@ Controller::NotifyCurrentFrameChanged(int32 frame) const
{
// check if we are still waiting to reach the seekframe,
// don't pass the event on to the listeners in that case
if ((system_time() - fLastSeekEventTime) < 1000000
&& fSeekFrame >= 0 && frame != fSeekFrame) {
if (fSeekRequested && fSeekFrame != frame)
return;
}
fSeekFrame = -1;
fSeekRequested = false;
float position = 0.0;
double duration = (double)fDuration * fVideoFrameRate / 1000000.0;
@ -1045,3 +1066,11 @@ Controller::NotifyStopFrameReached() const
_NotifyFileFinished();
}
void
Controller::NotifySeekHandled() const
{
fSeekRequested = false;
fSeekFrame = -1;
}

View File

@ -115,6 +115,8 @@ public:
void VolumeDown();
void ToggleMute();
void SetPosition(float value);
void SetFramePosition(int32 frame);
void SetTimePosition(bigtime_t position);
bool HasFile();
status_t GetFileFormatInfo(
@ -166,6 +168,7 @@ private:
virtual void NotifySpeedChanged(float speed) const;
virtual void NotifyFrameDropped() const;
virtual void NotifyStopFrameReached() const;
virtual void NotifySeekHandled() const;
VideoView* fVideoView;
@ -187,8 +190,9 @@ private:
mutable bigtime_t fPosition;
bigtime_t fDuration;
float fVideoFrameRate;
mutable int32 fSeekFrame;
bigtime_t fLastSeekEventTime;
mutable bool fSeekRequested;
mutable int32 fSeekFrame;
ListenerAdapter fGlobalSettingsListener;

View File

@ -50,7 +50,6 @@ MainApp::MainApp()
:
BApplication(kAppSig),
fPlayerCount(0),
fFirstWindow(NULL),
fSettingsWindow(NULL),
fOpenFilePanel(NULL),
@ -94,25 +93,12 @@ MainApp::QuitRequested()
}
BWindow*
MainApp::FirstWindow()
{
BAutolock _(this);
if (fFirstWindow != NULL)
return fFirstWindow;
return NewWindow();
}
BWindow*
MainWin*
MainApp::NewWindow()
{
BAutolock _(this);
fPlayerCount++;
BWindow* window = new MainWin(fFirstWindow == NULL);
if (fFirstWindow == NULL)
fFirstWindow = window;
return window;
return new(std::nothrow) MainWin(fPlayerCount == 1);
}
@ -157,7 +143,18 @@ MainApp::ReadyToRun()
}
// make sure we have at least one window open
FirstWindow();
if (fPlayerCount == 0) {
MainWin* window = NewWindow();
if (window == NULL) {
PostMessage(B_QUIT_REQUESTED);
return;
}
BMessage lastPlaylistArchive;
if (_RestoreCurrentPlaylist(&lastPlaylistArchive) == B_OK)
window->OpenPlaylist(&lastPlaylistArchive);
window->Show();
}
// setup the settings window now, we need to have it
fSettingsWindow = new SettingsWindow(BRect(150, 150, 450, 520));
@ -175,13 +172,13 @@ MainApp::RefsReceived(BMessage* message)
// ArgvReceived() but without MIME type check.
// For each file we create a new window and send it a
// B_REFS_RECEIVED message with a single file.
// If IsLaunching() is true, we use fFirstWindow as first
// window.
printf("MainApp::RefsReceived\n");
BWindow* window = NewWindow();
if (window)
if (window != NULL) {
window->Show();
window->PostMessage(message);
}
}
@ -231,8 +228,6 @@ MainApp::MessageReceived(BMessage* message)
&& message->FindBool("audio only", &audioOnly) == B_OK
&& message->FindRect("window frame", &windowFrame) == B_OK
&& message->FindInt64("creation time", &creationTime) == B_OK) {
if (window == fFirstWindow)
fFirstWindow = NULL;
if (audioOnly) {
if (!fAudioWindowFrameSaved
|| creationTime < fLastSavedAudioWindowCreationTime) {
@ -245,6 +240,15 @@ MainApp::MessageReceived(BMessage* message)
}
}
}
// Store the playlist if there is one. Since the app is doing
// this, it is "atomic". If the user has multiple instances
// playing audio at the same time, the last instance which is
// quit wins.
BMessage playlistArchive;
if (message->FindMessage("playlist", &playlistArchive) == B_OK)
_StoreCurrentPlaylist(&playlistArchive);
// quit if this was the last player window
fPlayerCount--;
if (fPlayerCount == 0)
@ -340,7 +344,13 @@ MainApp::MessageReceived(BMessage* message)
void
MainApp::AboutRequested()
{
FirstWindow()->PostMessage(B_ABOUT_REQUESTED);
BAlert* alert = new BAlert("about", NAME"\n\n Written by Marcus Overhagen "
", Stephan Aßmus and Frederik Modéen", "Thanks");
alert->SetFeel(B_FLOATING_ALL_WINDOW_FEEL);
// Make sure it is on top of any player windows that may have the
// floating all window feel.
alert->Go(NULL);
// asynchronous mode
}
@ -508,6 +518,43 @@ MainApp::_HandleFilePanelResult(BFilePanel* panel, const BMessage* message)
}
static const char* kCurrentPlaylistFilename = "MediaPlayer Current Playlist";
void
MainApp::_StoreCurrentPlaylist(const BMessage* message) const
{
BPath path;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK
|| path.Append(kCurrentPlaylistFilename) != B_OK) {
return;
}
BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
if (file.InitCheck() != B_OK)
return;
message->Flatten(&file);
}
status_t
MainApp::_RestoreCurrentPlaylist(BMessage* message) const
{
BPath path;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK
|| path.Append(kCurrentPlaylistFilename) != B_OK) {
return B_ERROR;
}
BFile file(path.Path(), B_READ_ONLY);
if (file.InitCheck() != B_OK)
return B_ERROR;
return message->Unflatten(&file);
}
// #pragma mark - main

View File

@ -49,6 +49,10 @@ enum {
M_MEDIA_SERVER_QUIT = 'msqt'
};
#define NAME "MediaPlayer"
class BFilePanel;
class SettingsWindow;
@ -58,8 +62,7 @@ public:
MainApp();
virtual ~MainApp();
BWindow* FirstWindow();
BWindow* NewWindow();
MainWin* NewWindow();
int32 PlayerCount() const;
private:
@ -81,13 +84,20 @@ private:
const char* defaultTitle,
const char* defaultLabel);
void _HandleOpenPanelResult(const BMessage* message);
void _HandleSavePanelResult(const BMessage* message);
void _HandleOpenPanelResult(
const BMessage* message);
void _HandleSavePanelResult(
const BMessage* message);
void _HandleFilePanelResult(BFilePanel* panel,
const BMessage* message);
void _StoreCurrentPlaylist(
const BMessage* message) const;
status_t _RestoreCurrentPlaylist(
BMessage* message) const;
private:
int32 fPlayerCount;
BWindow* fFirstWindow;
SettingsWindow* fSettingsWindow;
BFilePanel* fOpenFilePanel;

View File

@ -53,7 +53,6 @@
#include "PlaylistWindow.h"
#include "Settings.h"
#define NAME "MediaPlayer"
#define MIN_WIDTH 250
@ -129,7 +128,8 @@ MainWin::MainWin(bool isFirstWindow)
fWidthAspect(0),
fHeightAspect(0),
fMouseDownTracking(false),
fGlobalSettingsListener(this)
fGlobalSettingsListener(this),
fInitialSeekPosition(0)
{
// Handle window position and size depending on whether this is the
// first window or not. Use the window size from the window that was
@ -218,8 +218,6 @@ MainWin::MainWin(bool isFirstWindow)
AddShortcut('y', B_COMMAND_KEY, new BMessage(B_UNDO));
AddShortcut('z', B_COMMAND_KEY | B_SHIFT_KEY, new BMessage(B_REDO));
AddShortcut('y', B_COMMAND_KEY | B_SHIFT_KEY, new BMessage(B_REDO));
Show();
}
@ -367,7 +365,7 @@ MainWin::DispatchMessage(BMessage *msg, BHandler *handler)
void
MainWin::MessageReceived(BMessage *msg)
MainWin::MessageReceived(BMessage* msg)
{
// msg->PrintToStream();
switch (msg->what) {
@ -549,19 +547,8 @@ MainWin::MessageReceived(BMessage *msg)
ShowPlaylistWindow();
break;
case B_ABOUT_REQUESTED:
{
BAlert *alert;
alert = new BAlert("about", NAME"\n\n Written by Marcus Overhagen "
", Stephan Aßmus and Frederik Modéen", "Thanks");
if (fAlwaysOnTop) {
_ToggleAlwaysOnTop();
alert->Go(NULL); // Asynchronous mode
_ToggleAlwaysOnTop();
} else {
alert->Go(NULL); // Asynchronous mode
}
be_app->PostMessage(msg);
break;
}
case M_FILE_CLOSE:
PostMessage(B_QUIT_REQUESTED);
break;
@ -728,7 +715,7 @@ MainWin::QuitRequested()
message.AddBool("audio only", !fHasVideo);
message.AddInt64("creation time", fCreationTime);
if (!fHasVideo && fHasAudio) {
// store playlist and position if this is audio
// store playlist, current index and position if this is audio
BMessage playlistArchive;
BAutolock controllerLocker(fController);
@ -737,6 +724,8 @@ MainWin::QuitRequested()
BAutolock playlistLocker(fPlaylist);
if (fPlaylist->Archive(&playlistArchive) != B_OK
|| playlistArchive.AddInt32("index",
fPlaylist->CurrentItemIndex()) != B_OK
|| message.AddMessage("playlist", &playlistArchive) != B_OK) {
fprintf(stderr, "Failed to store current playlist.\n");
}
@ -756,6 +745,29 @@ MainWin::MenusBeginning()
// #pragma mark -
void
MainWin::OpenPlaylist(const BMessage* playlistArchive)
{
if (playlistArchive == NULL)
return;
BAutolock _(this);
BAutolock playlistLocker(fPlaylist);
if (fPlaylist->Unarchive(playlistArchive) != B_OK)
return;
int32 currentIndex;
if (playlistArchive->FindInt32("index", &currentIndex) != B_OK)
currentIndex = 0;
fPlaylist->SetCurrentItemIndex(currentIndex);
playlistLocker.Unlock();
playlistArchive->FindInt64("position", (int64*)&fInitialSeekPosition);
}
void
MainWin::OpenPlaylistItem(const PlaylistItemRef& item)
{
@ -794,6 +806,8 @@ MainWin::OpenPlaylistItem(const PlaylistItemRef& item)
fHasVideo = fController->VideoTrackCount() != 0;
fHasAudio = fController->AudioTrackCount() != 0;
SetTitle(item->Name().String());
fController->SetTimePosition(fInitialSeekPosition);
fInitialSeekPosition = 0;
}
_SetupWindow();
}

View File

@ -56,6 +56,7 @@ public:
virtual bool QuitRequested();
virtual void MenusBeginning();
void OpenPlaylist(const BMessage* playlistArchive);
void OpenPlaylistItem(const PlaylistItemRef& item);
void ShowFileInfo();
@ -162,6 +163,7 @@ private:
ListenerAdapter fGlobalSettingsListener;
bool fCloseWhenDonePlayingMovie;
bool fCloseWhenDonePlayingSound;
bigtime_t fInitialSeekPosition;
static int sNoVideoWidth;
};

View File

@ -42,9 +42,32 @@ struct PlaybackManager::PlayingState {
int32 play_mode;
int32 loop_mode;
bool looping_enabled;
bool is_seek_request;
int64 current_frame; // Playlist frame
int64 range_index; // playing range index of current_frame
int64 activation_frame; // absolute video frame
PlayingState()
{
}
PlayingState(const PlayingState& other)
:
start_frame(other.start_frame),
end_frame(other.end_frame),
frame_count(other.frame_count),
first_visible_frame(other.first_visible_frame),
last_visible_frame(other.last_visible_frame),
max_frame_count(other.max_frame_count),
play_mode(other.play_mode),
loop_mode(other.loop_mode),
looping_enabled(other.looping_enabled),
is_seek_request(false),
current_frame(other.current_frame),
range_index(other.range_index),
activation_frame(other.activation_frame)
{
}
};
@ -116,6 +139,7 @@ PlaybackManager::Init(float frameRate, int32 loopingMode, bool loopingEnabled,
state->play_mode = MODE_PLAYING_PAUSED_FORWARD;
state->loop_mode = loopingMode;
state->looping_enabled = loopingEnabled;
state->is_seek_request = false;
state->current_frame = currentFrame;
state->activation_frame = 0;
fStates.AddItem(state);
@ -356,10 +380,13 @@ PlaybackManager::DurationChanged()
void
PlaybackManager::SetCurrentFrame(int64 frame)
{
if (_LastState()->current_frame == frame)
if (_LastState()->current_frame == frame) {
NotifySeekHandled();
return;
}
PlayingState* newState = new PlayingState(*_LastState());
newState->current_frame = frame;
newState->is_seek_request = true;
_PushState(newState, false);
}
@ -731,7 +758,7 @@ PlaybackManager::GetPlaylistTimeInterval(bigtime_t startTime,
bigtime_t endTimeForFrame = TimeForFrame(endFrame);
endTime = min(endTime, endTimeForFrame);
bigtime_t intervalLength = endTime - startTime;
// Finally determine the time bounds for the Playlist interval (depending
// on the playing direction).
switch (playingDirection) {
@ -741,7 +768,7 @@ PlaybackManager::GetPlaylistTimeInterval(bigtime_t startTime,
// xStartTime = PlaylistTimeForFrame(xStartFrame)
// + startTime - TimeForFrame(startFrame);
// xEndTime = xStartTime + intervalLength;
// TODO: The current method does not handle the times the same way.
// It may happen, that for the same performance time different
// Playlist times (within a frame) are returned when passing it
@ -829,7 +856,7 @@ return result;
/*! Returns the Playlist frame for an Playlist time.
It holds PlaylistTimeForFrame(frame) <= time <
It holds PlaylistTimeForFrame(frame) <= time <
PlaylistTimeForFrame(frame + 1). */
int64
PlaybackManager::PlaylistFrameForTime(bigtime_t time) const
@ -1053,7 +1080,14 @@ PlaybackManager::NotifyFrameDropped() const
void
PlaybackManager::NotifyStopFrameReached() const
{
// not currently implemented in PlaybackListener interface
// not currently implemented in PlaybackListener interface
}
void
PlaybackManager::NotifySeekHandled() const
{
// not currently implemented in PlaybackListener interface
}
@ -1101,95 +1135,96 @@ PlaybackManager::_PushState(PlayingState* state, bool adjustCurrentFrame)
// debugger("PlaybackManager::_PushState() used before Init()\n");
TRACE("PlaybackManager::_PushState()\n");
if (state) {
// unset fStopPlayingFrame
int64 oldStopPlayingFrame = fStopPlayingFrame;
fStopPlayingFrame = -1;
// get last state
PlayingState* lastState = _LastState();
int64 activationFrame = max(max(state->activation_frame,
lastState->activation_frame),
NextFrame());
if (state == NULL)
return;
// unset fStopPlayingFrame
int64 oldStopPlayingFrame = fStopPlayingFrame;
fStopPlayingFrame = -1;
// get last state
PlayingState* lastState = _LastState();
int64 activationFrame = max(max(state->activation_frame,
lastState->activation_frame),
NextFrame());
TRACE(" state activation frame: %lld, last state activation frame: %lld, "
"NextFrame(): %lld\n", state->activation_frame, lastState->activation_frame,
NextFrame());
int64 currentFrame = 0;
// remember the current frame, if necessary
if (adjustCurrentFrame)
currentFrame = PlaylistFrameAtFrame(activationFrame);
// check whether it is active
// (NOTE: We may want to keep the last state, if it is not active,
// but then the new state should become active after the last one.
// Thus we had to replace `NextFrame()' with `activationFrame'.)
if (lastState->activation_frame >= NextFrame()) {
// it isn't -- remove it
fStates.RemoveItem(fStates.CountItems() - 1);
int64 currentFrame = 0;
// remember the current frame, if necessary
if (adjustCurrentFrame)
currentFrame = PlaylistFrameAtFrame(activationFrame);
// check whether it is active
// (NOTE: We may want to keep the last state, if it is not active,
// but then the new state should become active after the last one.
// Thus we had to replace `NextFrame()' with `activationFrame'.)
if (lastState->activation_frame >= NextFrame()) {
// it isn't -- remove it
fStates.RemoveItem(fStates.CountItems() - 1);
TRACE("deleting last \n");
PrintState(lastState);
delete lastState;
} else {
// it is -- keep it
}
// adjust the new state's current frame and activation frame
if (adjustCurrentFrame)
state->current_frame = currentFrame;
int32 playingDirection = _PlayingDirectionFor(state);
if (playingDirection != 0) {
state->current_frame
= _NextFrameInRange(state, state->current_frame);
} else {
// If not playing, we check at least, if the current frame lies
// within the interval [0, max_frame_count).
if (state->current_frame >= state->max_frame_count)
state->current_frame = state->max_frame_count - 1;
if (state->current_frame < 0)
state->current_frame = 0;
}
state->range_index = _RangeFrameForFrame(state, state->current_frame);
state->activation_frame = activationFrame;
fStates.AddItem(state);
delete lastState;
} else {
// it is -- keep it
}
// adjust the new state's current frame and activation frame
if (adjustCurrentFrame)
state->current_frame = currentFrame;
int32 playingDirection = _PlayingDirectionFor(state);
if (playingDirection != 0) {
state->current_frame
= _NextFrameInRange(state, state->current_frame);
} else {
// If not playing, we check at least, if the current frame lies
// within the interval [0, max_frame_count).
if (state->current_frame >= state->max_frame_count)
state->current_frame = state->max_frame_count - 1;
if (state->current_frame < 0)
state->current_frame = 0;
}
state->range_index = _RangeFrameForFrame(state, state->current_frame);
state->activation_frame = activationFrame;
fStates.AddItem(state);
PrintState(state);
TRACE("_PushState: state count: %ld\n", fStates.CountItems());
// push a new speed info
SpeedInfo* speedInfo = new SpeedInfo(*_LastSpeedInfo());
if (playingDirection == 0)
speedInfo->speed = 1.0;
else
speedInfo->speed = speedInfo->set_speed;
speedInfo->activation_frame = state->activation_frame;
_PushSpeedInfo(speedInfo);
// If the new state is a playing state and looping is turned off,
// determine when playing shall stop.
if (playingDirection != 0 && !state->looping_enabled) {
int64 startFrame, endFrame, frameCount;
_GetPlayingBoundsFor(state, startFrame, endFrame, frameCount);
if (playingDirection == -1)
swap(startFrame, endFrame);
// If we shall stop at the frame we start, set the current frame
// to the beginning of the range.
// We have to take care, since this state may equal the one
// before (or probably differs in just one (unimportant)
// parameter). This happens for instance, if the user changes the
// data or start/end frame... while playing. In this case setting
// the current frame to the start frame is unwanted. Therefore
// we check whether the previous state was intended to stop
// at the activation frame of this state.
if (oldStopPlayingFrame != state->activation_frame
&& state->current_frame == endFrame && frameCount > 1) {
state->current_frame = startFrame;
state->range_index
= _RangeFrameForFrame(state, state->current_frame);
}
if (playingDirection == 1) { // forward
fStopPlayingFrame = state->activation_frame
+ frameCount - state->range_index - 1;
} else { // backwards
fStopPlayingFrame = state->activation_frame
+ state->range_index;
}
_CheckStopPlaying();
// push a new speed info
SpeedInfo* speedInfo = new SpeedInfo(*_LastSpeedInfo());
if (playingDirection == 0)
speedInfo->speed = 1.0;
else
speedInfo->speed = speedInfo->set_speed;
speedInfo->activation_frame = state->activation_frame;
_PushSpeedInfo(speedInfo);
// If the new state is a playing state and looping is turned off,
// determine when playing shall stop.
if (playingDirection != 0 && !state->looping_enabled) {
int64 startFrame, endFrame, frameCount;
_GetPlayingBoundsFor(state, startFrame, endFrame, frameCount);
if (playingDirection == -1)
swap(startFrame, endFrame);
// If we shall stop at the frame we start, set the current frame
// to the beginning of the range.
// We have to take care, since this state may equal the one
// before (or probably differs in just one (unimportant)
// parameter). This happens for instance, if the user changes the
// data or start/end frame... while playing. In this case setting
// the current frame to the start frame is unwanted. Therefore
// we check whether the previous state was intended to stop
// at the activation frame of this state.
if (oldStopPlayingFrame != state->activation_frame
&& state->current_frame == endFrame && frameCount > 1) {
state->current_frame = startFrame;
state->range_index
= _RangeFrameForFrame(state, state->current_frame);
}
if (playingDirection == 1) { // forward
fStopPlayingFrame = state->activation_frame
+ frameCount - state->range_index - 1;
} else { // backwards
fStopPlayingFrame = state->activation_frame
+ state->range_index;
}
_CheckStopPlaying();
}
TRACE("PlaybackManager::_PushState() done\n");
}
@ -1213,6 +1248,11 @@ PlaybackManager::_UpdateStates()
TRACE("_UpdateStates: states removed: %ld, state count: %ld\n",
firstActive, fStates.CountItems());
}
PlayingState* currentState = _StateAt(firstActive);
if (currentState != NULL && currentState->is_seek_request) {
currentState->is_seek_request = false;
NotifySeekHandled();
}
}

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright (c) 2000-2008, Ingo Weinhold <ingo_weinhold@gmx.de>,
* Copyright (c) 2000-2008, Stephan Aßmus <superstippi@gmx.de>,
* All Rights Reserved. Distributed under the terms of the MIT license.
@ -169,6 +169,7 @@ public:
virtual void NotifySpeedChanged(float speed) const;
virtual void NotifyFrameDropped() const;
virtual void NotifyStopFrameReached() const;
virtual void NotifySeekHandled() const;
// debugging
void PrintState(PlayingState* state);

View File

@ -1,6 +1,6 @@
/*
* Copyright 2008 Stephan Aßmus <superstippi@gmx.de>.
* Copyright 1998 Eric Shepherd.
* Copyright 2008, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 1998, Eric Shepherd.
* All rights reserved. Distributed under the terms of the Be Sample Code
* license.
*/
@ -159,7 +159,7 @@ SettingsMessage::SetValue(const char* name, const BString& value)
status_t
SettingsMessage::SetValue(const char* name, const BPoint& value)
SettingsMessage::SetValue(const char* name, const BPoint& value)
{
if (ReplacePoint(name, value) == B_OK)
return B_OK;