Bug Summary

File:home/HaikuArchives/ArtPaint/artpaint/windows/BrushStoreWindow.cpp
Warning:line 270, column 3
Value stored to 'info' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-haiku -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name BrushStoreWindow.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /boot/system/lib/clang/12.0.1 -iquote ./ -iquote artpaint/ -iquote artpaint/Utilities/ -iquote artpaint/application/ -iquote artpaint/controls/ -iquote artpaint/layers/ -iquote artpaint/paintwindow/ -iquote artpaint/tools/ -iquote artpaint/viewmanipulators/ -iquote artpaint/windows/ -iquote objects_artpaint/ -isystem /boot/system/develop/headers/private/interface -internal-isystem /system/develop/headers/c++ -internal-isystem /system/develop/headers/c++/x86_64-unknown-haiku -internal-isystem /system/develop/headers/c++/backward -O3 -fdeprecated-macro -fdebug-compilation-dir /boot/home/HaikuArchives/ArtPaint -ferror-limit 19 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /tmp/scan-build-2022-06-19-103017-1294-1 -x c++ artpaint/windows/BrushStoreWindow.cpp
1/*
2 * Copyright 2003, Heikki Suhonen
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Heikki Suhonen <heikki.suhonen@gmail.com>
7 * Dale Cieslak <dcieslak@yahoo.com>
8 *
9 */
10
11#include "BrushStoreWindow.h"
12
13#include "Brush.h"
14#include "BrushEditor.h"
15#include "DrawingTools.h"
16#include "FloaterManager.h"
17#include "MessageFilters.h"
18#include "SettingsServer.h"
19#include "ToolManager.h"
20#include "ToolSetupWindow.h"
21#include "UtilityClasses.h"
22
23
24#include <Bitmap.h>
25#include <Catalog.h>
26#include <File.h>
27#include <MenuBar.h>
28#include <MenuItem.h>
29#include <Message.h>
30#include <ScrollBar.h>
31
32
33#undef B_TRANSLATION_CONTEXT"Windows"
34#define B_TRANSLATION_CONTEXT"Windows" "Windows"
35
36
37#define BRUSH_INSET2 2
38#define BRUSH_VAULT_WIDTH(64 +2*2) (BRUSH_PREVIEW_WIDTH64+2*BRUSH_INSET2)
39#define BRUSH_VAULT_HEIGHT(64 +2*2) (BRUSH_PREVIEW_WIDTH64+2*BRUSH_INSET2)
40
41BList* BrushStoreWindow::brush_data = new BList();
42BrushStoreWindow* BrushStoreWindow::brush_window = NULL__null;
43
44BrushStoreWindow::BrushStoreWindow()
45 : BWindow(BRect(20,20,220,220), B_TRANSLATE("Brushes")BLocaleRoster::Default()->GetCatalog()->GetString(("Brushes"
), "Windows")
,
46 B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_NOT_ZOOMABLE
47 | B_WILL_ACCEPT_FIRST_CLICK)
48{
49 BRect frame(20,20,220,220);
50 window_feel feel = B_NORMAL_WINDOW_FEEL;
51 if (SettingsServer* server = SettingsServer::Instance()) {
52 BMessage settings;
53 server->GetApplicationSettings(&settings);
54
55 settings.FindRect(skBrushWindowFrame, &frame);
56 settings.FindInt32(skBrushWindowFeel, (int32*)&feel);
57 server->SetValue(SettingsServer::Application, skBrushWindowVisible,
58 true);
59 }
60 frame = FitRectToScreen(frame);
61 MoveTo(frame.LeftTop());
62 ResizeTo(frame.Width(),frame.Height());
63
64 BMenuBar *menu_bar;
65 menu_bar = new BMenuBar(BRect(0,0,0,0),"brush window menu-bar");
66 BMenu *a_menu = new BMenu(B_TRANSLATE("Brush")BLocaleRoster::Default()->GetCatalog()->GetString(("Brush"
), "Windows")
);
67 menu_bar->AddItem(a_menu);
68 a_menu->AddItem(new BMenuItem(B_TRANSLATE("Delete selected brush")BLocaleRoster::Default()->GetCatalog()->GetString(("Delete selected brush"
), "Windows")
,
69 new BMessage(HS_DELETE_SELECTED_BRUSH'Dslb')));
70 AddChild(menu_bar);
71
72 BRect scroll_bar_frame = BRect(Bounds().right-B_V_SCROLL_BAR_WIDTH14.0f+1,menu_bar->Frame().bottom,Bounds().right+1,Bounds().bottom+1-B_H_SCROLL_BAR_HEIGHT14.0f);
73
74 scroll_bar = new BScrollBar(scroll_bar_frame,"brush store scroll-bar",NULL__null,0,0,B_VERTICAL);
75 AddChild(scroll_bar);
76 scroll_bar->SetRange(0,0);
77
78 store_view = new BrushStoreView(BRect(0,menu_bar->Frame().bottom + 1,scroll_bar->Frame().left-1,Bounds().bottom));
79 AddChild(store_view);
80
81 a_menu->FindItem(HS_DELETE_SELECTED_BRUSH'Dslb')->SetTarget(store_view);
82
83 store_view->MakeFocus(TRUE1);
84 scroll_bar->SetTarget(store_view);
85
86 // The adding of brushes will be done in a separate thread.
87 thread_id adder_thread = spawn_thread(brush_adder,"brush_adder",B_NORMAL_PRIORITY10,this);
88 resume_thread(adder_thread);
89
90 brush_window = this;
91
92 setFeel(feel);
93
94 SetSizeLimits(scroll_bar->Frame().Width()+BRUSH_VAULT_WIDTH(64 +2*2),10000,menu_bar->Frame().Height() + 1 + BRUSH_VAULT_HEIGHT(64 +2*2),10000);
95
96 // Add a filter that will be used to catch mouse-down-messages in order
97 // to activate this window when required
98 Lock();
99 BMessageFilter *activation_filter = new BMessageFilter(B_ANY_DELIVERY,B_ANY_SOURCE,B_MOUSE_DOWN,window_activation_filter);
100 AddCommonFilter(activation_filter);
101 AddCommonFilter(new BMessageFilter(B_KEY_DOWN,AppKeyFilterFunction));
102 Unlock();
103
104 // TODO: check what this is used for once Haiku implements this
105 SetWindowAlignment(B_PIXEL_ALIGNMENT, 0, 0, BRUSH_VAULT_WIDTH(64 +2*2),
106 int32(B_V_SCROLL_BAR_WIDTH14.0f + 1), 0, 0, BRUSH_VAULT_HEIGHT(64 +2*2),
107 int32(menu_bar->Bounds().Height() + 1));
108
109 FloaterManager::AddFloater(this);
110}
111
112
113BrushStoreWindow::~BrushStoreWindow()
114{
115 if (SettingsServer* server = SettingsServer::Instance()) {
116 server->SetValue(SettingsServer::Application, skBrushWindowFrame,
117 Frame());
118 server->SetValue(SettingsServer::Application, skBrushWindowVisible,
119 false);
120 }
121
122 FloaterManager::RemoveFloater(this);
123 brush_window = NULL__null;
124}
125
126
127void BrushStoreWindow::MessageReceived(BMessage *message)
128{
129 switch (message->what) {
130 default:
131 BWindow::MessageReceived(message);
132 break;
133 }
134}
135
136void BrushStoreWindow::writeBrushes(BFile &file)
137{
138 int32 number_of_brushes = brush_data->CountItems();
139 file.Write(&number_of_brushes,sizeof(int32));
140 for (int32 i=0;i<brush_data->CountItems();i++) {
141 file.Write((brush_data->ItemAt(i)),sizeof(brush_info));
142 }
143}
144
145void BrushStoreWindow::readBrushes(BFile &file)
146{
147 int32 number_of_brushes;
148 brush_info info;
149 if (file.Read(&number_of_brushes,sizeof(int32)) == sizeof(int32)) {
150 for (int32 i=0;i<number_of_brushes;i++) {
151 if (file.Read(&info,sizeof(brush_info)) == sizeof(brush_info)) {
152 brush_data->AddItem(new brush_info(info));
153 }
154 }
155 }
156}
157
158void BrushStoreWindow::AddBrush(Brush *brush)
159{
160 brush_data->AddItem(new brush_info(brush->GetInfo()));
161
162 if (brush_window != NULL__null) {
163 brush_window->Lock();
164 if (((BrushStoreWindow*)brush_window)->store_view != NULL__null)
165 ((BrushStoreWindow*)brush_window)->store_view->AddBrush(brush);
166 brush_window->Unlock();
167 }
168}
169
170void BrushStoreWindow::DeleteBrush(int32 index)
171{
172 brush_info *data;
173 data = (brush_info*)brush_data->RemoveItem(index);
174 delete data;
175}
176
177void BrushStoreWindow::showWindow()
178{
179 if (brush_window == NULL__null) {
180 new BrushStoreWindow();
181 brush_window->Show();
182 }
183 else {
184 brush_window->Lock();
185 brush_window->SetWorkspaces(B_CURRENT_WORKSPACE0);
186 if (brush_window->IsHidden()) {
187 brush_window->Show();
188 }
189 if (!brush_window->IsActive()) {
190 brush_window->Activate(TRUE1);
191 }
192 brush_window->Unlock();
193 }
194
195 BRect new_rect = FitRectToScreen(brush_window->Frame());
196 brush_window->MoveTo(new_rect.LeftTop());
197}
198
199void BrushStoreWindow::setFeel(window_feel feel)
200{
201 if (SettingsServer* server = SettingsServer::Instance()) {
202 server->SetValue(SettingsServer::Application, skBrushWindowFeel,
203 int32(feel));
204 }
205
206 if (brush_window != NULL__null) {
207 brush_window->Lock();
208 brush_window->SetFeel(feel);
209 float total_height = brush_window->store_view->Bounds().Height();
210 if (feel == B_NORMAL_WINDOW_FEEL) {
211 brush_window->SetLook(B_DOCUMENT_WINDOW_LOOK);
212 brush_window->scroll_bar->ResizeTo(B_V_SCROLL_BAR_WIDTH14.0f,total_height-B_H_SCROLL_BAR_HEIGHT14.0f+2);
213 }
214 else {
215 brush_window->SetLook(B_FLOATING_WINDOW_LOOK);
216 brush_window->scroll_bar->ResizeTo(B_V_SCROLL_BAR_WIDTH14.0f,total_height+2);
217 }
218 brush_window->Unlock();
219 }
220}
221
222
223int32 BrushStoreWindow::brush_adder(void *data)
224{
225 BrushStoreWindow *this_pointer = (BrushStoreWindow*)data;
226
227 if (this_pointer != NULL__null) {
228 BList temp_list(*brush_data);
229 if (temp_list.CountItems()> 0) {
230 Brush *a_brush = new Brush(*(brush_info*)(temp_list.ItemAt(0)));
231
232 for (int32 i=0;i<temp_list.CountItems();i++) {
233 a_brush->ModifyBrush(*(brush_info*)(temp_list.ItemAt(i)));
234 this_pointer->Lock();
235 this_pointer->store_view->AddBrush(a_brush);
236 this_pointer->Unlock();
237 }
238
239 delete a_brush;
240 }
241 return B_OK((int)0);
242 }
243 return B_ERROR(-1);
244}
245
246
247BrushStoreView::BrushStoreView(BRect frame)
248 : BView(frame,"brush store view",B_FOLLOW_ALL_rule_(_VIEW_TOP_, _VIEW_LEFT_, _VIEW_BOTTOM_, _VIEW_RIGHT_),B_WILL_DRAW|B_FRAME_EVENTS)
249{
250 brush_images = new BList();
251 brush_data = new BList();
252
253 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
254 selected_brush_index = 0;
255 previous_brush_index = 0;
256}
257
258
259BrushStoreView::~BrushStoreView()
260{
261 // Delete the brush-bitmaps from the list
262 BBitmap *a_bitmap;
263 while (brush_images->CountItems() > 0) {
264 a_bitmap = (BBitmap*)brush_images->RemoveItem((int32)0);
265 delete a_bitmap;
266 }
267
268 brush_info *info;
269 while (brush_data->CountItems() > 0) {
270 info = (brush_info*)brush_data->RemoveItem((int32)0);
Value stored to 'info' is never read
271 }
272
273 delete brush_images;
274 delete brush_data;
275}
276
277void BrushStoreView::DetachedFromWindow()
278{
279 BView *view = ScrollBar(B_VERTICAL);
280 if (view != NULL__null) {
281 view->RemoveSelf();
282 delete view;
283 }
284}
285
286
287void BrushStoreView::Draw(BRect area)
288{
289 SetHighColor(0,0,0,255);
290 SetPenSize(1.0);
291 for (int32 i=0;i<brush_images->CountItems();i++) {
292 if ((area & get_bitmap_frame(i)).IsValid() == TRUE1) {
293 DrawBitmapAsync((BBitmap*)brush_images->ItemAt(i),get_bitmap_frame(i));
294 BRect outer_frame = get_bitmap_frame(i);
295 outer_frame.InsetBy(-1,-1);
296 StrokeRect(outer_frame);
297 }
298 }
299 if (IsFocus() && (brush_data->CountItems() > 0)) {
300 BRect outer_frame = get_bitmap_frame(previous_brush_index);
301 outer_frame.InsetBy(-1,-1);
302 StrokeRect(outer_frame);
303
304 SetHighColor(0,0,255,255);
305 outer_frame = get_bitmap_frame(selected_brush_index);
306 outer_frame.InsetBy(-1,-1);
307 StrokeRect(outer_frame);
308 }
309 Sync();
310}
311
312void BrushStoreView::FrameResized(float width,float height)
313{
314 if (((int32)width/BRUSH_VAULT_WIDTH(64 +2*2)) != in_a_row) {
315 Invalidate();
316 in_a_row = (int32)width/BRUSH_VAULT_WIDTH(64 +2*2);
317 }
318 // At least one clumn, no matter how small the window is.
319 in_a_row = max_c(in_a_row,1)((in_a_row)>(1)?(in_a_row):(1));
320
321 int32 rows = (brush_data->CountItems() - 1) / in_a_row + 1;
322
323 BScrollBar *vertical_scrollbar = ScrollBar(B_VERTICAL);
324
325 if (vertical_scrollbar != NULL__null) {
326 if (rows*BRUSH_VAULT_HEIGHT(64 +2*2)>(height+1)) {
327 vertical_scrollbar->SetRange(0,rows*BRUSH_VAULT_HEIGHT(64 +2*2)-height);
328 vertical_scrollbar->SetProportion(height/(float)(rows*BRUSH_VAULT_HEIGHT(64 +2*2)));
329 }
330 else
331 vertical_scrollbar->SetRange(0,0);
332 }
333// float needed_width = in_a_row * BRUSH_VAULT_WIDTH;
334// if (needed_width != width)
335// Window()->ResizeBy(needed_width-width,0);
336}
337
338void BrushStoreView::MessageReceived(BMessage *message)
339{
340 brush_info *info;
341 Brush *a_brush;
342 ssize_t size;
343 switch (message->what) {
344 case HS_BRUSH_DRAGGED'Brdr':
345 if ((message->ReturnAddress() == BMessenger(this)) == FALSE0) {
346 message->FindData("brush data",B_ANY_TYPE,(const void**)&info,&size);
347 if (size == sizeof(brush_info)) {
348 a_brush = new Brush(*info);
349// AddBrush(a_brush);
350 BrushStoreWindow::AddBrush(a_brush);
351 delete a_brush;
352 }
353 }
354 else {
355 }
356 break;
357 case HS_DELETE_SELECTED_BRUSH'Dslb':
358 {
359 // In this case we delete the currently selected brush
360 // from the brush-list.
361 BBitmap *bitmap = (BBitmap*)brush_images->RemoveItem(selected_brush_index);
362 delete bitmap;
363 brush_info *data = (brush_info*)brush_data->RemoveItem(selected_brush_index);
364 delete data;
365
366 BrushStoreWindow::DeleteBrush(selected_brush_index);
367 if (brush_data->CountItems() <= selected_brush_index)
368 selected_brush_index--;
369
370 ResizeBy(-1,0);
371 ResizeBy(1,0);
372 Invalidate();
373 break;
374 }
375 default:
376 BView::MessageReceived(message);
377 break;
378 }
379}
380
381void BrushStoreView::KeyDown(const char *bytes,int32 numBytes)
382{
383 if (numBytes == 1) {
384 switch (bytes[0]) {
385 case B_DELETE:
386 {
387 // In this case we delete the currently selected brush
388 // from the brush-list.
389 BBitmap *bitmap = (BBitmap*)brush_images->RemoveItem(selected_brush_index);
390 delete bitmap;
391 brush_info *data = (brush_info*)brush_data->RemoveItem(selected_brush_index);
392 delete data;
393
394 BrushStoreWindow::DeleteBrush(selected_brush_index);
395 if (brush_data->CountItems() <= selected_brush_index)
396 selected_brush_index--;
397
398 ResizeBy(-1,0);
399 ResizeBy(1,0);
400 Invalidate();
401 break;
402 }
403 case B_LEFT_ARROW:
404 previous_brush_index = selected_brush_index;
405 if (selected_brush_index == 0)
406 selected_brush_index = brush_data->CountItems() - 1;
407 else
408 selected_brush_index = (selected_brush_index - 1) % brush_data->CountItems();
409 Draw(BRect(BPoint(0,0),BPoint(-1,-1)));
410 break;
411 case B_RIGHT_ARROW:
412 previous_brush_index = selected_brush_index;
413 selected_brush_index = (selected_brush_index + 1) % brush_data->CountItems();
414 Draw(BRect(BPoint(0,0),BPoint(-1,-1)));
415 break;
416 case B_UP_ARROW:
417// previous_brush_index = selected_brush_index;
418// selected_brush_index = (selected_brush_index - in_a_row);
419// if (selected_brush_index < 0)
420// selected_brush_index = brush_data->CountItems() + selected_brush_index;
421// % brush_data->CountItems();
422// Draw(BRect(BPoint(0,0),BPoint(-1,-1)));
423 break;
424 case B_DOWN_ARROW:
425// previous_brush_index = selected_brush_index;
426// selected_brush_index = (selected_brush_index + in_a_row) % brush_data->CountItems();
427// Draw(BRect(BPoint(0,0),BPoint(-1,-1)));
428 break;
429
430 default:
431 BView::KeyDown(bytes,numBytes);
432 break;
433 }
434 }
435}
436
437void BrushStoreView::MouseDown(BPoint point)
438{
439 if (!IsFocus())
440 MakeFocus(TRUE1);
441
442 uint32 buttons;
443 GetMouse(&point,&buttons);
444 BPoint original_point = point;
445
446 // Loop here until the button is released or user moves mouse enough to
447 // start a drag.
448// while (buttons && cont) {
449// GetMouse(&point,&buttons);
450// snooze(20.0 * 1000.0);
451// if (sqrt(pow(original_point.x-point.x,2)+pow(original_point.y-point.y,2)) > 6)
452// cont = FALSE;
453// }
454 int32 index = get_point_index(original_point);
455
456 if (index >= 0) {
457// if (sqrt(pow(original_point.x-point.x,2)+pow(original_point.y-point.y,2)) > 6) {
458// // In this case we drag a message.
459// BMessage *a_message = new BMessage(HS_BRUSH_DRAGGED);
460// a_message->AddData("brush data",B_ANY_TYPE,brush_data->ItemAt(index),sizeof(brush_info));
461// DragMessage(a_message,get_bitmap_frame(index));
462// delete a_message;
463// }
464// else {
465 // In this case we select the brush to be used with the brush tool.
466 // As we only have one brush tool, we should select the brush to be
467 // used no matter what button was pressed.
468// uint32 tool_type = ((PaintApplication*)be_app)->getTool(original_button);
469// DrawingTool *a_tool = ((PaintApplication*)be_app)->getDrawingTool(tool_type);
470// const DrawingTool *a_tool = tool_manager->ReturnTool(BRUSH_TOOL);
471// const BrushTool *brush_tool = cast_as(a_tool,const BrushTool);
472// if (brush_tool) {
473// Brush *a_brush = brush_tool->GetBrush();
474// a_brush->ModifyBrush(*((brush_info*)brush_data->ItemAt(index)));
475// BrushEditor::BrushModified();
476// a_brush->CreateDiffBrushes();
477// ToolSetupWindow::changeToolForTheSetupWindow(BRUSH_TOOL);
478//// ToolSetupWindow::updateTool(BRUSH_TOOL);
479//
480// }
481 ToolManager::Instance().SetCurrentBrush(((brush_info*)brush_data->ItemAt(index)));
482 ToolManager::Instance().ChangeTool(BRUSH_TOOL);
483// }
484 if (index != selected_brush_index) {
485 // If the selected brush changed, we must indicate it
486 // by drawing the view.
487 previous_brush_index = selected_brush_index;
488 selected_brush_index = index;
489 Draw(BRect(BPoint(0,0),BPoint(-1,-1)));
490 }
491 }
492}
493
494
495void BrushStoreView::AddBrush(Brush *brush)
496{
497 BBitmap *a_bitmap = new BBitmap(BRect(0,0,BRUSH_PREVIEW_WIDTH64-1,BRUSH_PREVIEW_HEIGHT64-1),B_RGB_32_BIT);
498
499 brush->PreviewBrush(a_bitmap);
500 brush_images->AddItem(a_bitmap);
501 brush_data->AddItem(new brush_info(brush->GetInfo()));
502
503 ResizeBy(-1,0);
504 ResizeBy(1,0);
505 Invalidate();
506}
507
508BRect BrushStoreView::get_bitmap_frame(int32 index)
509{
510 // First we get the info, how many brushes can be in a row.
511 int32 width = Bounds().IntegerWidth();
512 in_a_row = max_c(width/BRUSH_VAULT_WIDTH,1)((width/(64 +2*2))>(1)?(width/(64 +2*2)):(1));
513 int32 row_number = index/in_a_row;
514 int32 column_number = index-row_number*in_a_row;
515
516 BRect frame = BRect(column_number*BRUSH_VAULT_WIDTH(64 +2*2)+BRUSH_INSET2,row_number*BRUSH_VAULT_HEIGHT(64 +2*2)+BRUSH_INSET2,(column_number+1)*BRUSH_VAULT_WIDTH(64 +2*2)-1-BRUSH_INSET2,(row_number+1)*BRUSH_VAULT_HEIGHT(64 +2*2)-1-BRUSH_INSET2);
517 return frame;
518}
519
520
521int32 BrushStoreView::get_point_index(BPoint point)
522{
523 // First we get the info, how many brushes can be in a row.
524 int32 width = Bounds().IntegerWidth();
525 in_a_row = width/BRUSH_VAULT_WIDTH(64 +2*2);
526
527 // Then we check the row-number
528 int32 row_number = ((int32)point.y)/BRUSH_VAULT_HEIGHT(64 +2*2);
529
530 int32 index = -1;
531 if (point.y >= 0) {
532 index = row_number*in_a_row;
533 if (point.x >=0) {
534 index += (int32)point.x / BRUSH_VAULT_WIDTH(64 +2*2);
535 if (index > brush_images->CountItems()-1) {
536 index = -1;
537 }
538 }
539 }
540 return index;
541}