Fix some inconsistencies in object visibility/selectability tests.
[blender.git] / source / blender / editors / space_info / info_report.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Campbell Barton
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/editors/space_info/info_report.c
24  *  \ingroup spinfo
25  */
26
27
28 #include <stdlib.h>
29 #include <string.h>
30 #include <limits.h>
31
32 #include "MEM_guardedalloc.h"
33
34 #include "BLI_blenlib.h"
35 #include "BLI_dynstr.h"
36 #include "BLI_utildefines.h"
37
38 #include "BKE_context.h"
39
40 #include "WM_api.h"
41 #include "WM_types.h"
42
43 #include "ED_screen.h"
44
45 #include "RNA_access.h"
46 #include "RNA_define.h"
47
48 #include "info_intern.h"
49
50 int info_report_mask(SpaceInfo *UNUSED(sinfo))
51 {
52 #if 0
53         int report_mask = 0;
54
55         if (sinfo->rpt_mask & INFO_RPT_DEBUG) report_mask |= RPT_DEBUG_ALL;
56         if (sinfo->rpt_mask & INFO_RPT_INFO)  report_mask |= RPT_INFO_ALL;
57         if (sinfo->rpt_mask & INFO_RPT_OP)    report_mask |= RPT_OPERATOR_ALL;
58         if (sinfo->rpt_mask & INFO_RPT_WARN)  report_mask |= RPT_WARNING_ALL;
59         if (sinfo->rpt_mask & INFO_RPT_ERR)   report_mask |= RPT_ERROR_ALL;
60
61         return report_mask;
62 #endif
63
64         return RPT_DEBUG_ALL | RPT_INFO_ALL | RPT_OPERATOR_ALL | RPT_PROPERTY_ALL | RPT_WARNING_ALL | RPT_ERROR_ALL;
65 }
66
67 // TODO, get this working again!
68 static int report_replay_exec(bContext *C, wmOperator *UNUSED(op))
69 {
70 //      SpaceInfo *sc = CTX_wm_space_info(C);
71 //      ReportList *reports = CTX_wm_reports(C);
72 //      int report_mask = info_report_mask(sc);
73 //      Report *report;
74
75 #if 0
76         sc->type = CONSOLE_TYPE_PYTHON;
77
78         for (report = reports->list.last; report; report = report->prev) {
79                 if ((report->type & report_mask) &&
80                     (report->type & RPT_OPERATOR_ALL | RPT_PROPERTY_ALL) &&
81                     (report->flag & SELECT))
82                 {
83                         console_history_add_str(sc, report->message, 0);
84                         WM_operator_name_call(C, "CONSOLE_OT_execute", WM_OP_EXEC_DEFAULT, NULL);
85
86                         ED_area_tag_redraw(CTX_wm_area(C));
87                 }
88         }
89
90         sc->type = CONSOLE_TYPE_REPORT;
91 #endif
92         ED_area_tag_redraw(CTX_wm_area(C));
93
94         return OPERATOR_FINISHED;
95 }
96
97 void INFO_OT_report_replay(wmOperatorType *ot)
98 {
99         /* identifiers */
100         ot->name = "Replay Operators";
101         ot->description = "Replay selected reports";
102         ot->idname = "INFO_OT_report_replay";
103
104         /* api callbacks */
105         ot->poll = ED_operator_info_active;
106         ot->exec = report_replay_exec;
107
108         /* flags */
109         /* ot->flag = OPTYPE_REGISTER; */
110
111         /* properties */
112 }
113
114 static int select_report_pick_exec(bContext *C, wmOperator *op)
115 {
116         int report_index = RNA_int_get(op->ptr, "report_index");
117         Report *report = BLI_findlink(&CTX_wm_reports(C)->list, report_index);
118
119         if (!report)
120                 return OPERATOR_CANCELLED;
121
122         report->flag ^= SELECT; /* toggle */
123
124         ED_area_tag_redraw(CTX_wm_area(C));
125
126         return OPERATOR_FINISHED;
127 }
128
129 static int select_report_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
130 {
131         SpaceInfo *sinfo = CTX_wm_space_info(C);
132         ARegion *ar = CTX_wm_region(C);
133         ReportList *reports = CTX_wm_reports(C);
134         Report *report;
135
136         report = info_text_pick(sinfo, ar, reports, event->mval[1]);
137
138         RNA_int_set(op->ptr, "report_index", BLI_findindex(&reports->list, report));
139
140         return select_report_pick_exec(C, op);
141 }
142
143
144 void INFO_OT_select_pick(wmOperatorType *ot)
145 {
146         /* identifiers */
147         ot->name = "Select Report";
148         ot->description = "Select reports by index";
149         ot->idname = "INFO_OT_select_pick";
150
151         /* api callbacks */
152         ot->poll = ED_operator_info_active;
153         ot->invoke = select_report_pick_invoke;
154         ot->exec = select_report_pick_exec;
155
156         /* flags */
157         /* ot->flag = OPTYPE_REGISTER; */
158
159         /* properties */
160         RNA_def_int(ot->srna, "report_index", 0, 0, INT_MAX, "Report", "Index of the report", 0, INT_MAX);
161 }
162
163
164
165 static int report_select_all_toggle_exec(bContext *C, wmOperator *UNUSED(op))
166 {
167         SpaceInfo *sinfo = CTX_wm_space_info(C);
168         ReportList *reports = CTX_wm_reports(C);
169         int report_mask = info_report_mask(sinfo);
170         int deselect = 0;
171
172         Report *report;
173
174         for (report = reports->list.last; report; report = report->prev) {
175                 if ((report->type & report_mask) && (report->flag & SELECT)) {
176                         deselect = 1;
177                         break;
178                 }
179         }
180
181
182         if (deselect) {
183                 for (report = reports->list.last; report; report = report->prev)
184                         if (report->type & report_mask)
185                                 report->flag &= ~SELECT;
186         }
187         else {
188                 for (report = reports->list.last; report; report = report->prev)
189                         if (report->type & report_mask)
190                                 report->flag |= SELECT;
191         }
192
193         ED_area_tag_redraw(CTX_wm_area(C));
194
195         return OPERATOR_FINISHED;
196 }
197
198 void INFO_OT_select_all_toggle(wmOperatorType *ot)
199 {
200         /* identifiers */
201         ot->name = "(De)select All";
202         ot->description = "Select or deselect all reports";
203         ot->idname = "INFO_OT_select_all_toggle";
204
205         /* api callbacks */
206         ot->poll = ED_operator_info_active;
207         ot->exec = report_select_all_toggle_exec;
208
209         /* flags */
210         /*ot->flag = OPTYPE_REGISTER;*/
211
212         /* properties */
213 }
214
215 /* box_select operator */
216 static int box_select_exec(bContext *C, wmOperator *op)
217 {
218         SpaceInfo *sinfo = CTX_wm_space_info(C);
219         ARegion *ar = CTX_wm_region(C);
220         ReportList *reports = CTX_wm_reports(C);
221         int report_mask = info_report_mask(sinfo);
222         const bool extend = RNA_boolean_get(op->ptr, "extend");
223         Report *report_min, *report_max, *report;
224
225         //View2D *v2d = UI_view2d_fromcontext(C);
226
227
228         rcti rect;
229         //rctf rectf, rq;
230         const bool select = !RNA_boolean_get(op->ptr, "deselect");
231         //int mval[2];
232
233         WM_operator_properties_border_to_rcti(op, &rect);
234
235         if (!extend) {
236                 for (report = reports->list.first; report; report = report->next) {
237
238                         if ((report->type & report_mask) == 0)
239                                 continue;
240
241                         report->flag &= ~SELECT;
242                 }
243         }
244
245         report_min = info_text_pick(sinfo, ar, reports, rect.ymax);
246         report_max = info_text_pick(sinfo, ar, reports, rect.ymin);
247
248         /* get the first report if none found */
249         if (report_min == NULL) {
250                 // printf("find_min\n");
251                 for (report = reports->list.first; report; report = report->next) {
252                         if (report->type & report_mask) {
253                                 report_min = report;
254                                 break;
255                         }
256                 }
257         }
258
259         if (report_max == NULL) {
260                 // printf("find_max\n");
261                 for (report = reports->list.last; report; report = report->prev) {
262                         if (report->type & report_mask) {
263                                 report_max = report;
264                                 break;
265                         }
266                 }
267         }
268
269         if (report_min == NULL || report_max == NULL)
270                 return OPERATOR_CANCELLED;
271
272         for (report = report_min; (report != report_max->next); report = report->next) {
273
274                 if ((report->type & report_mask) == 0)
275                         continue;
276
277                 if (select)
278                         report->flag |= SELECT;
279                 else
280                         report->flag &= ~SELECT;
281         }
282
283         ED_area_tag_redraw(CTX_wm_area(C));
284
285         return OPERATOR_FINISHED;
286 }
287
288
289 /* ****** Box Select ****** */
290 void INFO_OT_select_box(wmOperatorType *ot)
291 {
292         /* identifiers */
293         ot->name = "Box Select";
294         ot->description = "Toggle box selection";
295         ot->idname = "INFO_OT_select_box";
296
297         /* api callbacks */
298         ot->invoke = WM_gesture_box_invoke;
299         ot->exec = box_select_exec;
300         ot->modal = WM_gesture_box_modal;
301         ot->cancel = WM_gesture_box_cancel;
302
303         ot->poll = ED_operator_info_active;
304
305         /* flags */
306         /* ot->flag = OPTYPE_REGISTER; */
307
308         /* rna */
309         WM_operator_properties_gesture_box_select(ot);
310 }
311
312
313
314 static int report_delete_exec(bContext *C, wmOperator *UNUSED(op))
315 {
316         SpaceInfo *sinfo = CTX_wm_space_info(C);
317         ReportList *reports = CTX_wm_reports(C);
318         int report_mask = info_report_mask(sinfo);
319
320
321         Report *report, *report_next;
322
323         for (report = reports->list.first; report; ) {
324
325                 report_next = report->next;
326
327                 if ((report->type & report_mask) && (report->flag & SELECT)) {
328                         BLI_remlink(&reports->list, report);
329                         MEM_freeN((void *)report->message);
330                         MEM_freeN(report);
331                 }
332
333                 report = report_next;
334         }
335
336         ED_area_tag_redraw(CTX_wm_area(C));
337
338         return OPERATOR_FINISHED;
339 }
340
341 void INFO_OT_report_delete(wmOperatorType *ot)
342 {
343         /* identifiers */
344         ot->name = "Delete Reports";
345         ot->description = "Delete selected reports";
346         ot->idname = "INFO_OT_report_delete";
347
348         /* api callbacks */
349         ot->poll = ED_operator_info_active;
350         ot->exec = report_delete_exec;
351
352         /* flags */
353         /*ot->flag = OPTYPE_REGISTER;*/
354
355         /* properties */
356 }
357
358
359 static int report_copy_exec(bContext *C, wmOperator *UNUSED(op))
360 {
361         SpaceInfo *sinfo = CTX_wm_space_info(C);
362         ReportList *reports = CTX_wm_reports(C);
363         int report_mask = info_report_mask(sinfo);
364
365         Report *report;
366
367         DynStr *buf_dyn = BLI_dynstr_new();
368         char *buf_str;
369
370         for (report = reports->list.first; report; report = report->next) {
371                 if ((report->type & report_mask) && (report->flag & SELECT)) {
372                         BLI_dynstr_append(buf_dyn, report->message);
373                         BLI_dynstr_append(buf_dyn, "\n");
374                 }
375         }
376
377         buf_str = BLI_dynstr_get_cstring(buf_dyn);
378         BLI_dynstr_free(buf_dyn);
379
380         WM_clipboard_text_set(buf_str, 0);
381
382         MEM_freeN(buf_str);
383         return OPERATOR_FINISHED;
384 }
385
386 void INFO_OT_report_copy(wmOperatorType *ot)
387 {
388         /* identifiers */
389         ot->name = "Copy Reports to Clipboard";
390         ot->description = "Copy selected reports to Clipboard";
391         ot->idname = "INFO_OT_report_copy";
392
393         /* api callbacks */
394         ot->poll = ED_operator_info_active;
395         ot->exec = report_copy_exec;
396
397         /* flags */
398         /*ot->flag = OPTYPE_REGISTER;*/
399
400         /* properties */
401 }