EditExtensionsRevamp: EditExtensionsRevamp.py

File EditExtensionsRevamp.py, 9.9 kB (added by ale, 22 months ago)

version 1.0

Line 
1# -*- coding: utf-8 -*-
2
3# EditExtensionsRevamp, Wikidpad plugin
4# by alessandro orsi
5# v1.0, 14 Sep 2011, license GPL
6
7
8
9import wx
10import re
11
12
13
14# === Wikidpad Keyboad Shortcut ===
15
16# Descriptor for EditorFunctions plugin type
17WIKIDPAD_PLUGIN = (("MenuFunctions",1),)
18
19def describeMenuItems(wiki):
20
21    """ Reads the keyboard shortcut from WP configuration file,
22        if it doesn't exist assign a default one """
23
24    keybindings = wiki.getKeyBindings()
25   
26    kb = keybindings.EdExRevamp
27   
28    if kb == '':
29       
30        kb = u'Ctrl-Alt-M'
31
32    return ((EdExtRevamp, u'Edit Extensions Revamp' + u'\t' + kb , 'A revamped Edit Extensions plugin'),)
33
34   
35   
36
37# === WX DIALOGUES ===
38
39class EdExtDialogue ( wx.Dialog ):
40       
41    """ Dialogue for the Insert before/after function """
42   
43    def __init__( self, parent ):
44        wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Edit Extensions Revamp", pos = wx.DefaultPosition, size = wx.Size( 269,183 ), style = wx.CAPTION|wx.STAY_ON_TOP )
45
46        self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
47
48        main_sizer = wx.BoxSizer( wx.VERTICAL )
49
50        self.label_before = wx.StaticText( self, wx.ID_ANY, u"Before:", wx.DefaultPosition, wx.DefaultSize, 0 )
51        self.label_before.Wrap( -1 )
52        main_sizer.Add( self.label_before, 0, wx.ALL, 5 )
53
54        self.txt_before = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
55        main_sizer.Add( self.txt_before, 0, wx.EXPAND|wx.LEFT|wx.RIGHT, 5 )
56
57        self.label_after = wx.StaticText( self, wx.ID_ANY, u"After", wx.DefaultPosition, wx.DefaultSize, 0 )
58        self.label_after.Wrap( -1 )
59        main_sizer.Add( self.label_after, 0, wx.ALL, 5 )
60
61        self.txt_after = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
62        main_sizer.Add( self.txt_after, 0, wx.EXPAND|wx.LEFT|wx.RIGHT, 5 )
63
64        btns_sizer = wx.StdDialogButtonSizer()
65        self.btns_sizerOK = wx.Button( self, wx.ID_OK )
66        btns_sizer.AddButton( self.btns_sizerOK )
67        self.btns_sizerCancel = wx.Button( self, wx.ID_CANCEL )
68        btns_sizer.AddButton( self.btns_sizerCancel )
69        btns_sizer.Realize();
70        main_sizer.Add( btns_sizer, 1, wx.ALIGN_RIGHT|wx.RIGHT, 5 )
71
72        self.SetSizer( main_sizer )
73        self.Layout()
74
75        self.Centre( wx.BOTH )
76       
77        # For Linux, or the control won't get the focus
78        self.txt_before.SetFocus()
79       
80
81
82# === FUNCTIONS ===
83
84def lowercase(wiki, evt, text):
85
86    """ Converts the selected text to lower case """
87
88    text = text.lower()
89
90    wiki.getActiveEditor().ReplaceSelection(text)
91
92   
93def uppercase(wiki, evt, text):
94
95    """ Converts the selected text to upper case """
96
97    text = text.upper()
98
99    wiki.getActiveEditor().ReplaceSelection(text)
100   
101   
102def invert_case(wiki, evt, text):
103
104    """ Inverts the case of each character in the selected text """
105
106    text = text.swapcase()
107
108    wiki.getActiveEditor().ReplaceSelection(text)
109   
110
111def title_case(wiki, evt, text):
112
113    """ Capitalizes the first character of each word in the selected text """
114
115    text = text.title()
116
117    wiki.getActiveEditor().ReplaceSelection(text)
118
119
120def sentence_case(wiki, evt, text):
121
122    """ Capitalizes the first character of each line in the selected text """
123
124    # Store lines in a list
125    lines = text.split('\n')
126
127    # Loop through each line
128    for line in range(len(lines)):
129
130        mod_line= ''
131        first_alpha_chr = True
132
133        # Loop through each character in a line
134        for pos in range(len(lines[line])):
135
136            # Check if it is an alphabetic character
137            if lines[line][pos].isalpha():
138
139
140                # If it's the first alphabetical character, capitalize
141                if first_alpha_chr:
142
143                    mod_line = mod_line + lines[line][pos].upper()
144                    first_alpha_chr = False
145
146                # otherwise convert to lower case
147                else:
148
149                    mod_line = mod_line + lines[line][pos].lower()
150
151
152            else:
153
154                # if char is not alphabhetic leave unchanged
155                mod_line = mod_line + lines[line][pos]
156
157
158        lines[line] = mod_line
159
160    # Convert the list in a string
161    modified_lines = '\n'.join(lines)
162
163    wiki.getActiveEditor().ReplaceSelection(modified_lines)
164
165   
166def trim_spaces(wiki, env,text):
167
168    """ Remove leading and trailing spaces from each line in the selection """
169
170    # Store lines in a list
171    lines = text.split('\n')
172
173    for id in range(len(lines)):
174
175        lines[id] = lines[id].strip()
176
177    # Convert the list in a string
178    modified_lines = '\n'.join(lines)
179
180    wiki.getActiveEditor().ReplaceSelection(modified_lines)
181
182
183def compress_spaces(wiki, env, text):
184
185    """ Leave only one space between words in the selection """
186
187    text = re.sub(r'[ ]{2,}', ' ', text)
188
189    wiki.getActiveEditor().ReplaceSelection(text)
190   
191
192def insert_before_after(wiki, evt, text):
193
194    """ Shows a dialog where the user can enter one or two strings
195    The strings are than added respectively at the beginning and at
196    the end of each line in the selection
197
198    """
199 
200    dlg = EdExtDialogue(wiki)
201
202    status = dlg.ShowModal()
203   
204    if status == wx.ID_CANCEL:
205        return
206   
207    before = dlg.txt_before.GetValue()
208    after = dlg.txt_after.GetValue()
209
210    dlg.Destroy()
211   
212    # User didn't enter any value but clicked OK
213    if before == after == '':
214        return
215   
216    # Store lines in a list
217    lines = text.split('\n')
218
219    for id in range(len(lines)):
220
221        # Modify line only if it's not blank
222        if lines[id] != '':
223            lines[id] = before + lines[id] + after
224
225    # Convert the list in a string
226    modified_lines = '\n'.join(lines)
227
228    wiki.getActiveEditor().ReplaceSelection(modified_lines)
229
230
231   
232   
233# === POP UP MENU ==
234
235def EdExtRevamp(wiki, evt):
236
237    """ Called by Wikidpad through the shortcut, builds and shows the popup menu """
238
239    class EdExtPopupMenu(wx.Menu):
240        def __init__(self, parent, sel):
241            wx.Menu.__init__(self)
242
243            self.parent = parent
244            self.sel = sel
245           
246            # Lower case
247            lower = wx.MenuItem(self, wx.NewId(), '&Lower')
248            self.AppendItem(lower)
249            self.Bind(wx.EVT_MENU, self.OnLower, id=lower.GetId())
250           
251            # Upper case
252            upper = wx.MenuItem(self, wx.NewId(), '&Upper')
253            self.AppendItem(upper)
254            self.Bind(wx.EVT_MENU, self.OnUpper, id=upper.GetId())
255
256            # Invert case
257            invert = wx.MenuItem(self, wx.NewId(), '&Invert')
258            self.AppendItem(invert)
259            self.Bind(wx.EVT_MENU, self.OnInvert, id=invert.GetId())
260           
261            # Title case
262            title = wx.MenuItem(self, wx.NewId(), '&Title')
263            self.AppendItem(title)
264            self.Bind(wx.EVT_MENU, self.OnTitle, id=title.GetId())
265
266            # Sentence case - works on multiple lines
267            sentence = wx.MenuItem(self, wx.NewId(), '&Sentence')
268            self.AppendItem(sentence)
269            self.Bind(wx.EVT_MENU, self.OnSentence, id=sentence.GetId())
270           
271            # Trim spaces - works on multiple lines
272            trim = wx.MenuItem(self, wx.NewId(), 'T&rim spaces')
273            self.AppendItem(trim)
274            self.Bind(wx.EVT_MENU, self.OnTrim, id=trim.GetId())                       
275           
276            # Compress spaces - works on multiple lines
277            compress = wx.MenuItem(self, wx.NewId(), '&Compress spaces')
278            self.AppendItem(compress)
279            self.Bind(wx.EVT_MENU, self.OnCompress, id=compress.GetId())
280           
281            # Insert before/after - works on multiple lines
282            insert_ba = wx.MenuItem(self, wx.NewId(), 'I&nsert before/after')
283            self.AppendItem(insert_ba)
284            self.Bind(wx.EVT_MENU, self.OnInsertBA, id=insert_ba.GetId())
285           
286
287        # Menu items events           
288       
289        def OnLower(self, event):
290            lowercase(wiki, evt, self.sel)
291
292        def OnUpper(self, event):
293            uppercase(wiki, evt, self.sel)
294           
295        def OnInvert(self, event):
296            invert_case(wiki, evt, self.sel)
297           
298        def OnTitle(self, event):
299            title_case(wiki, evt, self.sel)
300           
301        def OnSentence(self, event):
302            sentence_case(wiki, evt, self.sel)
303       
304        def OnTrim(self, event):
305            trim_spaces(wiki, evt, self.sel)
306
307        def OnCompress(self, event):
308            compress_spaces(wiki, evt, self.sel)       
309           
310        def OnInsertBA(self, event):
311            insert_before_after(wiki, evt, self.sel)
312           
313           
314   
315    # === CODE CALLED FROM WIKIDPAD STARTS HERE ===
316           
317    # Get selected text in the editor
318    Selection = wiki.getActiveEditor().GetSelectedText()
319
320    # Check if the selection is empty
321    if Selection == '':
322        wx.MessageBox('Please, select some text first', 'Info')
323        return
324   
325    # Store current caret position
326    pos = wiki.getActiveEditor().GetCurrentPos()
327   
328
329    # Convert caret position to pixel coordinates (relative to window)
330    point = wiki.getActiveEditor().PointFromPosition(pos)
331
332   
333    # Conver pixel coordinates relative to window to coordinates relative to screen
334    # otherwise the position of the popup will change depending on if the tree is
335    # showed or hidden
336    scr_coord = wiki.getActiveEditor().ClientToScreen(point)
337   
338    # Create the popup menu
339    wiki.PopupMenu(EdExtPopupMenu(wiki, Selection), scr_coord)
340   
341    # Put back the caret where it was
342    wiki.getActiveEditor().SetCurrentPos(pos)