RemoteDrawingEngine: Reduce RP_READ_BITMAP result timeout.
[haiku.git] / src / preferences / repositories / TaskTimer.cpp
blobf13a74876a6986ffa263768c6edb88974375c2b1
1 /*
2 * Copyright 2017 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Brian Hill
7 */
10 #include "TaskTimer.h"
12 #include <Application.h>
13 #include <Catalog.h>
15 #include "constants.h"
17 #undef B_TRANSLATION_CONTEXT
18 #define B_TRANSLATION_CONTEXT "TaskTimer"
20 static int32 sAlertStackCount = 0;
23 TaskTimer::TaskTimer(const BMessenger& target, Task* owner)
25 BLooper(),
26 fTimeoutMicroSeconds(kTimerTimeoutSeconds * 1000000),
27 fTimerIsRunning(false),
28 fReplyTarget(target),
29 fMessageRunner(NULL),
30 fTimeoutMessage(TASK_TIMEOUT),
31 fTimeoutAlert(NULL),
32 fOwner(owner)
34 Run();
36 // Messenger for the Message Runner to use to send its message to the timer
37 fMessenger.SetTo(this);
38 // Invoker for the Alerts to use to send their messages to the timer
39 fTimeoutAlertInvoker.SetMessage(
40 new BMessage(TIMEOUT_ALERT_BUTTON_SELECTION));
41 fTimeoutAlertInvoker.SetTarget(this);
45 TaskTimer::~TaskTimer()
47 if (fTimeoutAlert) {
48 fTimeoutAlert->Lock();
49 fTimeoutAlert->Quit();
51 if (fMessageRunner)
52 fMessageRunner->SetCount(0);
56 bool
57 TaskTimer::QuitRequested()
59 return true;
63 void
64 TaskTimer::MessageReceived(BMessage* message)
66 switch (message->what)
68 case TASK_TIMEOUT:
70 fMessageRunner = NULL;
71 if (fTimerIsRunning) {
72 BString text(B_TRANSLATE_COMMENT("The task for repository"
73 " %name% is taking a long time to complete.",
74 "Alert message. Do not translate %name%"));
75 BString nameString("\"");
76 nameString.Append(fRepositoryName).Append("\"");
77 text.ReplaceFirst("%name%", nameString);
78 fTimeoutAlert = new BAlert("timeout", text,
79 B_TRANSLATE_COMMENT("Keep trying", "Button label"),
80 B_TRANSLATE_COMMENT("Cancel task", "Button label"),
81 NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
82 fTimeoutAlert->SetShortcut(0, B_ESCAPE);
83 // Calculate the position to correctly stack this alert
84 BRect windowFrame = be_app->WindowAt(0)->Frame();
85 int32 stackPos = _NextAlertStackCount();
86 float xPos = windowFrame.left
87 + windowFrame.Width()/2 + stackPos * kTimerAlertOffset;
88 float yPos = windowFrame.top
89 + (stackPos + 1) * kTimerAlertOffset;
90 fTimeoutAlert->Go(&fTimeoutAlertInvoker);
91 xPos -= fTimeoutAlert->Frame().Width()/2;
92 // The correct frame for the alert is not available until
93 // after Go is called
94 fTimeoutAlert->MoveTo(xPos, yPos);
96 break;
99 case TIMEOUT_ALERT_BUTTON_SELECTION:
101 fTimeoutAlert = NULL;
102 // Timeout alert was invoked by user and timer still has not
103 // been stopped
104 if (fTimerIsRunning) {
105 // find which button was pressed
106 int32 selection = -1;
107 message->FindInt32("which", &selection);
108 if (selection == 1) {
109 BMessage reply(TASK_KILL_REQUEST);
110 reply.AddPointer(key_taskptr, fOwner);
111 fReplyTarget.SendMessage(&reply);
112 } else if (selection == 0) {
113 // Create new timer
114 fMessageRunner = new BMessageRunner(fMessenger,
115 &fTimeoutMessage, kTimerRetrySeconds * 1000000, 1);
118 break;
124 void
125 TaskTimer::Start(const char* name)
127 fTimerIsRunning = true;
128 fRepositoryName.SetTo(name);
130 // Create a message runner that will send a TASK_TIMEOUT message if the
131 // timer is not stopped
132 if (fMessageRunner == NULL) {
133 fMessageRunner = new BMessageRunner(fMessenger, &fTimeoutMessage,
134 fTimeoutMicroSeconds, 1);
136 else
137 fMessageRunner->SetInterval(fTimeoutMicroSeconds);
141 void
142 TaskTimer::Stop(const char* name)
144 fTimerIsRunning = false;
146 // Reset max timeout so we can reuse the runner at the next Start call
147 if (fMessageRunner != NULL)
148 fMessageRunner->SetInterval(LLONG_MAX);
150 // If timeout alert is showing replace it
151 if (fTimeoutAlert) {
152 // Remove current alert
153 BRect frame = fTimeoutAlert->Frame();
154 fTimeoutAlert->Quit();
155 fTimeoutAlert = NULL;
157 // Display new alert that won't send a message
158 BString text(B_TRANSLATE_COMMENT("Good news! The task for repository "
159 "%name% completed.", "Alert message. Do not translate %name%"));
160 BString nameString("\"");
161 nameString.Append(name).Append("\"");
162 text.ReplaceFirst("%name%", nameString);
163 BAlert* newAlert = new BAlert("timeout", text, kOKLabel, NULL, NULL,
164 B_WIDTH_AS_USUAL, B_WARNING_ALERT);
165 newAlert->SetShortcut(0, B_ESCAPE);
166 newAlert->MoveTo(frame.left, frame.top);
167 newAlert->Go(NULL);
172 int32
173 TaskTimer::_NextAlertStackCount()
175 if (sAlertStackCount > 9)
176 sAlertStackCount = 0;
177 return sAlertStackCount++;