UI: use icons for text edit copy/paste
[blender.git] / release / scripts / startup / bl_ui / space_text.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8-80 compliant>
20 import bpy
21 from bpy.types import Header, Menu, Panel
22 from bpy.app.translations import pgettext_iface as iface_
23
24
25 class TEXT_HT_header(Header):
26     bl_space_type = 'TEXT_EDITOR'
27
28     def draw(self, context):
29         layout = self.layout
30
31         st = context.space_data
32         text = st.text
33
34         row = layout.row(align=True)
35         row.template_header()
36
37         TEXT_MT_editor_menus.draw_collapsible(context, layout)
38
39         if text and text.is_modified:
40             sub = row.row(align=True)
41             sub.alert = True
42             sub.operator("text.resolve_conflict", text="", icon='HELP')
43
44         layout.separator_spacer()
45
46         row = layout.row(align=True)
47         row.template_ID(st, "text", new="text.new", unlink="text.unlink", open="text.open")
48
49         layout.separator_spacer()
50
51         row = layout.row(align=True)
52         row.prop(st, "show_line_numbers", text="")
53         row.prop(st, "show_word_wrap", text="")
54         row.prop(st, "show_syntax_highlight", text="")
55
56         if text:
57             is_osl = text.name.endswith((".osl", ".osl"))
58
59             row = layout.row()
60             if text.filepath:
61                 if text.is_dirty:
62                     row.label(
63                         text=iface_(f"File: *{text.filepath:s} (unsaved)"),
64                         translate=False,
65                     )
66                 else:
67                     row.label(
68                         text=iface_(f"File: {text.filepath:s}"),
69                         translate=False,
70                     )
71             else:
72                 row.label(
73                     text="Text: External"
74                     if text.library
75                     else "Text: Internal"
76                 )
77             if is_osl:
78                 row = layout.row()
79                 row.operator("node.shader_script_update")
80             else:
81                 row = layout.row()
82                 row.active = text.name.endswith(".py")
83                 row.prop(text, "use_module")
84
85                 row = layout.row()
86                 row.operator("text.run_script")
87
88
89 class TEXT_MT_editor_menus(Menu):
90     bl_idname = "TEXT_MT_editor_menus"
91     bl_label = ""
92
93     def draw(self, context):
94         self.draw_menus(self.layout, context)
95
96     @staticmethod
97     def draw_menus(layout, context):
98         st = context.space_data
99         text = st.text
100
101         layout.menu("TEXT_MT_view")
102         layout.menu("TEXT_MT_text")
103
104         if text:
105             layout.menu("TEXT_MT_edit")
106             layout.menu("TEXT_MT_format")
107
108         layout.menu("TEXT_MT_templates")
109
110
111 class TEXT_PT_properties(Panel):
112     bl_space_type = 'TEXT_EDITOR'
113     bl_region_type = 'UI'
114     bl_category = "Text"
115     bl_label = "Properties"
116
117     def draw(self, context):
118         layout = self.layout
119
120         st = context.space_data
121
122         flow = layout.column_flow()
123         flow.prop(st, "show_line_numbers")
124         flow.prop(st, "show_word_wrap")
125         flow.prop(st, "show_syntax_highlight")
126         flow.prop(st, "show_line_highlight")
127         flow.prop(st, "use_live_edit")
128
129         flow = layout.column_flow()
130         flow.prop(st, "font_size")
131         flow.prop(st, "tab_width")
132
133         text = st.text
134         if text:
135             flow.prop(text, "use_tabs_as_spaces")
136
137         flow.prop(st, "show_margin")
138         col = flow.column()
139         col.active = st.show_margin
140         col.prop(st, "margin_column")
141
142
143 class TEXT_PT_find(Panel):
144     bl_space_type = 'TEXT_EDITOR'
145     bl_region_type = 'UI'
146     bl_category = "Text"
147     bl_label = "Find"
148
149     def draw(self, context):
150         layout = self.layout
151
152         st = context.space_data
153
154         # find
155         col = layout.column(align=True)
156         row = col.row(align=True)
157         row.prop(st, "find_text", text="")
158         row.operator("text.find_set_selected", text="", icon='TEXT')
159         col.operator("text.find")
160
161         # replace
162         col = layout.column(align=True)
163         row = col.row(align=True)
164         row.prop(st, "replace_text", text="")
165         row.operator("text.replace_set_selected", text="", icon='TEXT')
166         col.operator("text.replace")
167
168         # settings
169         layout.prop(st, "use_match_case")
170         row = layout.row(align=True)
171         row.prop(st, "use_find_wrap", text="Wrap")
172         row.prop(st, "use_find_all", text="All")
173
174
175 class TEXT_MT_view(Menu):
176     bl_label = "View"
177
178     def draw(self, context):
179         layout = self.layout
180
181         layout.operator("text.properties", icon='MENU_PANEL')
182
183         layout.separator()
184
185         layout.operator("text.move",
186                         text="Top of File",
187                         ).type = 'FILE_TOP'
188         layout.operator("text.move",
189                         text="Bottom of File",
190                         ).type = 'FILE_BOTTOM'
191
192         layout.separator()
193
194         layout.menu("INFO_MT_area")
195
196
197 class TEXT_MT_text(Menu):
198     bl_label = "Text"
199
200     def draw(self, context):
201         layout = self.layout
202
203         st = context.space_data
204         text = st.text
205
206         layout.operator("text.new")
207         layout.operator("text.open")
208
209         if text:
210             layout.operator("text.reload")
211
212             layout.column()
213             layout.operator("text.save")
214             layout.operator("text.save_as")
215
216             if text.filepath:
217                 layout.operator("text.make_internal")
218
219             layout.column()
220             layout.operator("text.run_script")
221
222
223 class TEXT_MT_templates_py(Menu):
224     bl_label = "Python"
225
226     def draw(self, context):
227         self.path_menu(
228             bpy.utils.script_paths("templates_py"),
229             "text.open",
230             props_default={"internal": True},
231         )
232
233
234 class TEXT_MT_templates_osl(Menu):
235     bl_label = "Open Shading Language"
236
237     def draw(self, context):
238         self.path_menu(
239             bpy.utils.script_paths("templates_osl"),
240             "text.open",
241             props_default={"internal": True},
242         )
243
244
245 class TEXT_MT_templates(Menu):
246     bl_label = "Templates"
247
248     def draw(self, context):
249         layout = self.layout
250         layout.menu("TEXT_MT_templates_py")
251         layout.menu("TEXT_MT_templates_osl")
252
253
254 class TEXT_MT_edit_select(Menu):
255     bl_label = "Select"
256
257     def draw(self, context):
258         layout = self.layout
259
260         layout.operator("text.select_all")
261         layout.operator("text.select_line")
262
263
264 class TEXT_MT_format(Menu):
265     bl_label = "Format"
266
267     def draw(self, context):
268         layout = self.layout
269
270         layout.operator("text.indent")
271         layout.operator("text.unindent")
272
273         layout.separator()
274
275         layout.operator("text.comment")
276         layout.operator("text.uncomment")
277
278         layout.separator()
279
280         layout.operator_menu_enum("text.convert_whitespace", "type")
281
282
283 class TEXT_MT_edit_to3d(Menu):
284     bl_label = "Text To 3D Object"
285
286     def draw(self, context):
287         layout = self.layout
288
289         layout.operator("text.to_3d_object",
290                         text="One Object",
291                         ).split_lines = False
292         layout.operator("text.to_3d_object",
293                         text="One Object Per Line",
294                         ).split_lines = True
295
296
297 class TEXT_MT_edit(Menu):
298     bl_label = "Edit"
299
300     @classmethod
301     def poll(cls, context):
302         return (context.space_data.text)
303
304     def draw(self, context):
305         layout = self.layout
306
307         layout.operator("ed.undo")
308         layout.operator("ed.redo")
309
310         layout.separator()
311
312         layout.operator("text.cut")
313         layout.operator("text.copy", icon='COPYDOWN')
314         layout.operator("text.paste", icon='PASTEDOWN')
315         layout.operator("text.duplicate_line")
316
317         layout.separator()
318
319         layout.operator("text.move_lines",
320                         text="Move line(s) up").direction = 'UP'
321         layout.operator("text.move_lines",
322                         text="Move line(s) down").direction = 'DOWN'
323
324         layout.separator()
325
326         layout.menu("TEXT_MT_edit_select")
327
328         layout.separator()
329
330         layout.operator("text.jump")
331         layout.operator("text.start_find", text="Find...")
332         layout.operator("text.autocomplete")
333
334         layout.separator()
335
336         layout.menu("TEXT_MT_edit_to3d")
337
338
339 class TEXT_MT_toolbox(Menu):
340     bl_label = ""
341
342     def draw(self, context):
343         layout = self.layout
344
345         layout.operator_context = 'INVOKE_DEFAULT'
346
347         layout.operator("text.cut")
348         layout.operator("text.copy")
349         layout.operator("text.paste")
350
351         layout.separator()
352
353         layout.operator("text.run_script")
354
355
356 classes = (
357     TEXT_HT_header,
358     TEXT_MT_edit,
359     TEXT_MT_editor_menus,
360     TEXT_PT_properties,
361     TEXT_PT_find,
362     TEXT_MT_view,
363     TEXT_MT_text,
364     TEXT_MT_templates,
365     TEXT_MT_templates_py,
366     TEXT_MT_templates_osl,
367     TEXT_MT_edit_select,
368     TEXT_MT_format,
369     TEXT_MT_edit_to3d,
370     TEXT_MT_toolbox,
371 )
372
373 if __name__ == "__main__":  # only for live edit.
374     from bpy.utils import register_class
375     for cls in classes:
376         register_class(cls)