~ubuntu-branches/ubuntu/maverick/lfm/maverick-proposed

« back to all changes in this revision

Viewing changes to lfm/actions.py

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2004-07-26 18:08:07 UTC
  • Revision ID: james.westby@ubuntu.com-20040726180807-ocycfymqg3pvz22o
Tags: upstream-0.91.2
ImportĀ upstreamĀ versionĀ 0.91.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: iso-8859-15 -*-
 
2
 
 
3
"""actions.py
 
4
 
 
5
This module contains the actions when key pressed.
 
6
"""
 
7
 
 
8
 
 
9
import os, os.path
 
10
import sys
 
11
import time
 
12
from glob import glob
 
13
import curses
 
14
 
 
15
from __init__ import *
 
16
import files
 
17
from utils import *
 
18
import vfs
 
19
import messages
 
20
import pyview
 
21
 
 
22
 
 
23
##################################################
 
24
##### global variables
 
25
##################################################
 
26
app = None
 
27
 
 
28
 
 
29
##################################################
 
30
##### actions
 
31
##################################################
 
32
keytable= {
 
33
    # movement
 
34
    ord('p'): 'cursor_up',
 
35
    ord('P'): 'cursor_up',
 
36
    curses.KEY_UP: 'cursor_up',
 
37
    ord('d'): 'cursor_down',
 
38
    ord('D'): 'cursor_down',
 
39
    curses.KEY_DOWN: 'cursor_down',
 
40
    curses.KEY_PPAGE: 'page_previous',
 
41
    curses.KEY_BACKSPACE: 'page_previous',
 
42
    0x08: 'page_previous',      # BackSpace
 
43
    0x10: 'page_previous',      # Ctrl-P
 
44
    curses.KEY_NPAGE: 'page_next',
 
45
    ord(' '): 'page_next',
 
46
    0x0E: 'page_next',          # Ctrl-N
 
47
    curses.KEY_HOME: 'home',
 
48
    0x16A: 'home',
 
49
    0x001: 'home',
 
50
    curses.KEY_END: 'end',
 
51
    0x181: 'end',
 
52
    0x005: 'end',
 
53
 
 
54
    # change dir
 
55
    curses.KEY_LEFT: 'cursor_left',
 
56
    curses.KEY_RIGHT: 'cursor_right',
 
57
    10: 'enter',
 
58
    13: 'enter',
 
59
    ord('g'): 'goto_dir',
 
60
    ord('G'): 'goto_dir',
 
61
    0x13: 'goto_file',          # Ctrl-S
 
62
    0x14: 'tree',               # Ctrl-T
 
63
    ord('0'): 'bookmark_0',
 
64
    ord('1'): 'bookmark_1',
 
65
    ord('2'): 'bookmark_2',
 
66
    ord('3'): 'bookmark_3',
 
67
    ord('4'): 'bookmark_4',
 
68
    ord('5'): 'bookmark_5',
 
69
    ord('6'): 'bookmark_6',
 
70
    ord('7'): 'bookmark_7',
 
71
    ord('8'): 'bookmark_8',
 
72
    ord('9'): 'bookmark_9',
 
73
    0x04: 'select_bookmark',    # Ctrl-D
 
74
    ord('b'): 'set_bookmark',
 
75
    ord('B'): 'set_bookmark',
 
76
 
 
77
    # panels
 
78
    ord('\t'): 'change_panel',  # tab
 
79
    ord('.'): 'toggle_panels',
 
80
    ord(','): 'swap_panels',
 
81
    0x15: 'swap_panels',        # Ctrl-U
 
82
    ord('='): 'same_panels',
 
83
 
 
84
    # selections
 
85
    curses.KEY_IC: 'select_item',
 
86
    ord('+'): 'select_group',
 
87
    ord('-'): 'deselect_group',
 
88
    ord('*'): 'invert_select',
 
89
 
 
90
    # misc
 
91
    ord('#'): 'show_size',
 
92
    ord('s'): 'sort',
 
93
    ord('S'): 'sort',
 
94
    ord('i'): 'file_info',
 
95
    ord('I'): 'file_info',
 
96
    ord('@'): 'do_something_on_file',
 
97
    0xF1: 'special_regards',    # special regards
 
98
    ord('/'): 'find_grep',
 
99
    ord('t'): 'touch_file',
 
100
    ord('T'): 'touch_file',
 
101
    ord('l'): 'create_link',
 
102
    ord('L'): 'create_link',
 
103
    0x0C: 'edit_link',          # Ctrl-L
 
104
    0x0F: 'open_shell',         # Ctrl-O
 
105
 
 
106
    # main functions
 
107
    ord('v'): 'view_file',
 
108
    ord('V'): 'view_file',
 
109
    curses.KEY_F3: 'view_file',
 
110
    ord('e'): 'edit_file',
 
111
    ord('E'): 'edit_file',
 
112
    curses.KEY_F4: 'edit_file',
 
113
    ord('c'): 'copy',
 
114
    ord('C'): 'copy',
 
115
    curses.KEY_F5: 'copy',
 
116
    ord('m'): 'move',
 
117
    ord('M'): 'move',
 
118
    curses.KEY_F6: 'move',
 
119
    ord('r'): 'rename',
 
120
    ord('R'): 'rename',
 
121
    curses.KEY_F7: 'make_dir',
 
122
    ord('d'): 'delete',
 
123
    ord('D'): 'delete',
 
124
    curses.KEY_DC: 'delete',
 
125
    curses.KEY_F8: 'delete',
 
126
 
 
127
    # menu
 
128
    ord('h'): 'show_help',
 
129
    ord('H'): 'show_help',
 
130
    curses.KEY_F1: 'show_help',
 
131
    ord('f'): 'file_menu',
 
132
    ord('F'): 'file_menu',
 
133
    curses.KEY_F2: 'file_menu',
 
134
    curses.KEY_F9: 'general_menu',
 
135
 
 
136
    # terminal resize:
 
137
    curses.KEY_RESIZE: 'resize_window',
 
138
    
 
139
    # quit & exit
 
140
    ord('q'): 'quit',
 
141
    ord('Q'): 'quit',
 
142
    curses.KEY_F10: 'quit',   
 
143
    ord('x'): 'exit',
 
144
    ord('X'): 'exit'
 
145
}
 
146
 
 
147
 
 
148
def do(_app, panel, ch):
 
149
    global app
 
150
    app = _app
 
151
    try:
 
152
        act = 'ret = %s(panel)'  % keytable[ch]
 
153
    except KeyError:
 
154
        curses.beep()
 
155
    else:
 
156
        exec(act)
 
157
        return ret
 
158
 
 
159
 
 
160
##################################################
 
161
##### actions
 
162
##################################################
 
163
 
 
164
# movement
 
165
def cursor_up(panel):
 
166
    panel.file_i -= 1
 
167
    panel.fix_limits()
 
168
 
 
169
 
 
170
def cursor_down(panel):
 
171
    panel.file_i += 1
 
172
    panel.fix_limits()
 
173
 
 
174
 
 
175
def page_previous(panel):
 
176
    panel.file_i -= panel.dims[0]
 
177
    if panel.pos == 1 or panel.pos == 2:
 
178
        panel.file_i += 3
 
179
    panel.fix_limits()
 
180
 
 
181
 
 
182
def page_next(panel):
 
183
    panel.file_i += panel.dims[0]
 
184
    if panel.pos == 1 or panel.pos == 2:
 
185
        panel.file_i -= 3
 
186
    panel.fix_limits()
 
187
 
 
188
 
 
189
def home(panel):
 
190
    panel.file_i = 0
 
191
    panel.fix_limits()
 
192
 
 
193
 
 
194
def end(panel):
 
195
    panel.file_i = panel.nfiles - 1
 
196
    panel.fix_limits()
 
197
 
 
198
 
 
199
# change dir
 
200
def cursor_left(panel):
 
201
    if not panel.vfs:
 
202
        if panel.path != os.sep:
 
203
            olddir = os.path.basename(panel.path)
 
204
            panel.init_dir(os.path.dirname(panel.path))
 
205
            panel.file_i = panel.sorted.index(olddir)
 
206
            panel.fix_limits()
 
207
    else:
 
208
        if panel.path == panel.base:
 
209
            olddir = os.path.basename(panel.vbase).replace('#vfs', '')
 
210
            vfs.exit(app, panel)                          
 
211
            panel.init_dir(os.path.dirname(panel.vbase))
 
212
            panel.file_i = panel.sorted.index(olddir)
 
213
            panel.fix_limits()
 
214
        else:
 
215
            olddir = os.path.basename(panel.path)
 
216
            pvfs, base, vbase = panel.vfs, panel.base, panel.vbase
 
217
            panel.init_dir(os.path.dirname(panel.path))
 
218
            panel.vfs, panel.base, panel.vbase = pvfs, base, vbase
 
219
            panel.file_i = panel.sorted.index(olddir)
 
220
            panel.fix_limits()
 
221
 
 
222
 
 
223
def cursor_right(panel):
 
224
    filename = panel.sorted[panel.file_i]
 
225
    vfstype = check_compressed_tarfile(app, filename)
 
226
    if panel.files[filename][files.FT_TYPE] == files.FTYPE_DIR:
 
227
        if not panel.vfs:
 
228
            if filename == os.pardir:
 
229
                olddir = os.path.basename(panel.path)
 
230
                panel.init_dir(os.path.dirname(panel.path))
 
231
                panel.file_i = panel.sorted.index(olddir)
 
232
                panel.fix_limits()
 
233
            else:
 
234
                panel.init_dir(os.path.join(panel.path, filename))
 
235
 
 
236
        else:
 
237
            if panel.path == panel.base and filename == os.pardir:
 
238
                olddir = os.path.basename(panel.vbase).replace('#vfs', '')
 
239
                vfs.exit(app, panel)                          
 
240
                panel.init_dir(os.path.dirname(panel.vbase))
 
241
                panel.file_i = panel.sorted.index(olddir)
 
242
                panel.fix_limits()
 
243
            else:
 
244
                pvfs, base, vbase = panel.vfs, panel.base, panel.vbase
 
245
                panel.init_dir(os.path.join(panel.path, filename))
 
246
                panel.vfs, panel.base, panel.vbase = pvfs, base, vbase
 
247
    elif panel.files[filename][files.FT_TYPE] == files.FTYPE_LNK2DIR:
 
248
        panel.init_dir(files.get_linkpath(panel.path, filename))
 
249
    elif (panel.files[filename][files.FT_TYPE] == files.FTYPE_REG or \
 
250
       panel.files[filename][files.FT_TYPE] == files.FTYPE_LNK) and \
 
251
       vfstype != -1:
 
252
        vfs.init(app, panel, filename, vfstype)
 
253
    else:
 
254
        return
 
255
 
 
256
 
 
257
def enter(panel):
 
258
    filename = panel.sorted[panel.file_i]
 
259
    vfstype = check_compressed_tarfile(app, filename)
 
260
    if (panel.files[filename][files.FT_TYPE] == files.FTYPE_REG or \
 
261
       panel.files[filename][files.FT_TYPE] == files.FTYPE_LNK) and \
 
262
       vfstype != -1:
 
263
        vfs.init(app, panel, filename, vfstype)
 
264
    elif panel.files[filename][files.FT_TYPE] == files.FTYPE_DIR:
 
265
        if not panel.vfs:
 
266
            if filename == os.pardir:
 
267
                olddir = os.path.basename(panel.path)
 
268
                panel.init_dir(os.path.dirname(panel.path))
 
269
                panel.file_i = panel.sorted.index(olddir)
 
270
                panel.fix_limits()
 
271
            else:
 
272
                panel.init_dir(os.path.join(panel.path, filename))
 
273
        else:
 
274
            if panel.path == panel.base and filename == os.pardir:
 
275
                olddir = os.path.basename(panel.vbase).replace('#vfs', '')
 
276
                vfs.exit(app, panel)                          
 
277
                panel.init_dir(os.path.dirname(panel.vbase))
 
278
                panel.file_i = panel.sorted.index(olddir)
 
279
                panel.fix_limits()
 
280
            else:
 
281
                pvfs, base, vbase = panel.vfs, panel.base, panel.vbase
 
282
                panel.init_dir(os.path.join(panel.path, filename))
 
283
                panel.vfs, panel.base, panel.vbase = pvfs, base, vbase
 
284
    elif panel.files[filename][files.FT_TYPE] == files.FTYPE_LNK2DIR:
 
285
        panel.init_dir(files.get_linkpath(panel.path, filename))
 
286
    elif panel.files[filename][files.FT_TYPE] == files.FTYPE_EXE:
 
287
        do_execute_file(panel)
 
288
    elif panel.files[filename][files.FT_TYPE] == files.FTYPE_REG:
 
289
        do_special_view_file(panel)
 
290
    else:
 
291
        return
 
292
 
 
293
 
 
294
def goto_dir(panel):
 
295
    todir = doEntry('Go to directory', 'Type directory name')
 
296
    app.show()
 
297
    if todir == None or todir == "":
 
298
        return
 
299
    todir = os.path.join(panel.path, todir)
 
300
    if panel.vfs:
 
301
        vfs.exit(app, panel)
 
302
    panel.init_dir(todir)
 
303
    panel.fix_limits()
 
304
 
 
305
 
 
306
def goto_file(panel):
 
307
    tofile = doEntry('Go to file', 'Type how file name begins')
 
308
    app.show()
 
309
    if tofile == None or tofile == "":
 
310
        return
 
311
    thefiles = panel.sorted[panel.file_i:]
 
312
    for f in thefiles:
 
313
        if f.find(tofile) == 0:
 
314
            break
 
315
    else:
 
316
        return
 
317
    panel.file_i = panel.sorted.index(f)
 
318
    panel.fix_limits()
 
319
 
 
320
 
 
321
def tree(panel):
 
322
    if panel.vfs:
 
323
        return
 
324
    panel_i = app.panel
 
325
    app.panel = not panel_i
 
326
    panel.show()
 
327
    t = Tree(panel.path, panel.pos)
 
328
    ans = t.run()
 
329
    del(t)
 
330
    app.panel = panel_i
 
331
    if ans != -1:
 
332
        panel.init_dir(ans)
 
333
        panel.fix_limits()
 
334
 
 
335
 
 
336
def bookmark_0(panel):
 
337
    goto_bookmark(panel, 0)
 
338
 
 
339
 
 
340
def bookmark_1(panel):
 
341
    goto_bookmark(panel, 1)
 
342
 
 
343
 
 
344
def bookmark_2(panel):
 
345
    goto_bookmark(panel, 2)
 
346
 
 
347
 
 
348
def bookmark_3(panel):
 
349
    goto_bookmark(panel, 3)
 
350
 
 
351
 
 
352
def bookmark_4(panel):
 
353
    goto_bookmark(panel, 4)
 
354
 
 
355
 
 
356
def bookmark_5(panel):
 
357
    goto_bookmark(panel, 5)
 
358
 
 
359
 
 
360
def bookmark_6(panel):
 
361
    goto_bookmark(panel, 6)
 
362
 
 
363
 
 
364
def bookmark_7(panel):
 
365
    goto_bookmark(panel, 7)
 
366
 
 
367
 
 
368
def bookmark_8(panel):
 
369
    goto_bookmark(panel, 8)
 
370
 
 
371
 
 
372
def bookmark_9(panel):
 
373
    goto_bookmark(panel, 9)
 
374
 
 
375
 
 
376
def select_bookmark(panel):
 
377
    cmd = messages.MenuWin('Select Bookmark', app.prefs.bookmarks).run()
 
378
    if cmd == -1:
 
379
        return
 
380
    if panel.vfs:
 
381
        vfs.exit(app, panel)
 
382
    panel.init_dir(cmd)
 
383
    panel.fix_limits()
 
384
 
 
385
 
 
386
def set_bookmark(panel):
 
387
    if panel.vfs:
 
388
        messages.error('Set bookmark', 'Can\'t bookmark inside vfs')
 
389
        return
 
390
    while 1:
 
391
        ch = messages.get_a_key('Set bookmark',
 
392
                                'Press 0-9 to save the bookmark, Ctrl-C to quit')
 
393
        if 0x30 <= ch <= 0x39:         # 0..9
 
394
            app.prefs.bookmarks[ch-0x30] = panel.path[:]
 
395
            break
 
396
        elif ch == -1:                 # Ctrl-C
 
397
            break
 
398
 
 
399
 
 
400
# panels
 
401
def change_panel(panel):
 
402
    if panel.pos == 3:
 
403
        return
 
404
    return app.panel
 
405
 
 
406
    
 
407
def toggle_panels(panel):
 
408
    if panel.pos == 3:
 
409
        # now => 2 panels mode
 
410
        app.panels[0].pos = 1
 
411
        app.panels[1].pos = 2
 
412
    else:
 
413
        # now => full panel mode
 
414
        if app.panel == 0:
 
415
            app.panels[0].pos = 3
 
416
            app.panels[1].pos = 0
 
417
        else:
 
418
            app.panels[0].pos = 0
 
419
            app.panels[1].pos = 3
 
420
    app.panels[0].init_curses(app.panels[0].pos)
 
421
    app.panels[1].init_curses(app.panels[1].pos)
 
422
    panel.fix_limits()
 
423
    app.get_otherpanel().fix_limits()
 
424
 
 
425
 
 
426
def swap_panels(panel):
 
427
    if panel.pos == 3:
 
428
        return
 
429
    otherpanel = app.get_otherpanel()
 
430
    panel.pos, otherpanel.pos = otherpanel.pos, panel.pos
 
431
    panel.init_curses(panel.pos)
 
432
    otherpanel.init_curses(otherpanel.pos)
 
433
 
 
434
 
 
435
def same_panels(panel):
 
436
    otherpanel = app.get_otherpanel()
 
437
    if not panel.vfs:
 
438
        if otherpanel.vfs:
 
439
            vfs.exit(app, otherpanel)
 
440
        otherpanel.init_dir(panel.path)
 
441
        otherpanel.fix_limits()
 
442
    else:
 
443
        if panel.vfs == 'pan':
 
444
            vfs.pan_copy(app, panel, otherpanel)
 
445
        else:
 
446
            vfs.copy(app, panel, otherpanel)
 
447
        pvfs, base, vbase = otherpanel.vfs, otherpanel.base, otherpanel.vbase
 
448
        otherpanel.init_dir(base + panel.path.replace(panel.base, ''))
 
449
        otherpanel.fix_limits()
 
450
        otherpanel.vfs, otherpanel.base, otherpanel.vbase = pvfs, base, vbase
 
451
 
 
452
 
 
453
# selections
 
454
def select_item(panel):
 
455
    filename = panel.sorted[panel.file_i]
 
456
    if filename == os.pardir:
 
457
        panel.file_i += 1
 
458
        panel.fix_limits()
 
459
        return
 
460
    try:
 
461
        panel.selections.index(filename)
 
462
    except ValueError:
 
463
        panel.selections.append(filename)
 
464
    else:
 
465
        panel.selections.remove(filename)
 
466
    panel.file_i += 1
 
467
    panel.fix_limits()
 
468
 
 
469
 
 
470
def select_group(panel):
 
471
    pattern = doEntry('Select group', 'Type pattern', '*')
 
472
    if pattern == None or pattern == '':
 
473
        return
 
474
    fullpath = os.path.join(panel.path, pattern)
 
475
    [panel.selections.append(os.path.basename(f)) for f in glob(fullpath)]
 
476
 
 
477
 
 
478
def deselect_group(panel):
 
479
    pattern = doEntry('Deselect group', 'Type pattern', '*')
 
480
    if pattern == None or pattern == '':
 
481
        return
 
482
    fullpath = os.path.join(panel.path, pattern)
 
483
    for f in [os.path.basename(f) for f in glob(fullpath)]:
 
484
        if f in panel.selections:
 
485
            panel.selections.remove(f)
 
486
 
 
487
def invert_select(panel):
 
488
    selections_old = panel.selections[:]
 
489
    panel.selections = []
 
490
    for f in panel.sorted:
 
491
        if f not in selections_old and f != os.pardir:
 
492
            panel.selections.append(f)
 
493
 
 
494
 
 
495
# misc
 
496
def show_size(panel):
 
497
    show_dirs_size(panel)
 
498
 
 
499
 
 
500
def sort(panel):
 
501
    app.show()
 
502
    sort(panel)
 
503
 
 
504
 
 
505
def file_info(panel):
 
506
    do_show_file_info(panel)
 
507
 
 
508
 
 
509
def do_something_on_file(panel):
 
510
    do_something_on_file(panel)
 
511
 
 
512
 
 
513
def special_regards(panel):
 
514
    messages.win('Special Regards',
 
515
                 '   Maite zaitut, Montse\n   T\'estimo molt, Montse')
 
516
 
 
517
 
 
518
def find_grep(panel):
 
519
    findgrep(panel)
 
520
 
 
521
 
 
522
def touch_file(panel):
 
523
    newfile = doEntry('Touch file', 'Type file name')
 
524
    if newfile == None or newfile == "":
 
525
        return
 
526
    fullfilename = os.path.join(panel.path, newfile)
 
527
    i, err = os.popen4('touch \"%s\"' % fullfilename)
 
528
    err = err.read().split(':')[-1:][0].strip()
 
529
    if err:
 
530
        app.show()
 
531
        messages.error('Touch file', '%s: %s' % (newfile, err))
 
532
    curses.curs_set(0)
 
533
    panel.refresh_panel(panel)
 
534
    panel.refresh_panel(app.get_otherpanel())
 
535
 
 
536
 
 
537
def create_link(panel):
 
538
    otherpanel = app.get_otherpanel()
 
539
    if panel.path != otherpanel.path:
 
540
        otherfile = os.path.join(otherpanel.path,
 
541
                                 otherpanel.sorted[otherpanel.file_i])
 
542
    else:
 
543
        otherfile = otherpanel.sorted[otherpanel.file_i]
 
544
    newlink, pointto = doDoubleEntry('Create link',
 
545
                                     'Link name', '', 1, 1,
 
546
                                     'Pointing to', otherfile, 1, 1)
 
547
    if newlink == None or pointto == None:
 
548
        return
 
549
    if newlink == '':
 
550
        app.show()
 
551
        messages.error('Edit link', 'You must type new link name')
 
552
        return
 
553
    if pointto == '':
 
554
        app.show()
 
555
        messages.error('Edit link', 'You must type pointed file')
 
556
        return
 
557
    fullfilename = os.path.join(panel.path, newlink)
 
558
    ans = files.create_link(pointto, fullfilename)
 
559
    if ans:
 
560
        app.show()
 
561
        messages.error('Edit link', '%s (%s)' % (ans,
 
562
                       self.sorted[self.file_i]))
 
563
    panel.refresh_panel(panel)
 
564
    panel.refresh_panel(app.get_otherpanel())
 
565
 
 
566
 
 
567
def edit_link(panel):
 
568
    fullfilename = os.path.join(panel.path, panel.sorted[panel.file_i])
 
569
    if not os.path.islink(fullfilename):
 
570
        return
 
571
    pointto = doEntry('Edit link', 'Link \'%s\' points to' % \
 
572
                      panel.sorted[panel.file_i],
 
573
                      os.readlink(fullfilename))
 
574
    if pointto == None or pointto == "":
 
575
        return
 
576
    if pointto != None and pointto != "" and \
 
577
       pointto != os.readlink(fullfilename):
 
578
        ans = files.modify_link(pointto, fullfilename)
 
579
        if ans:
 
580
            app.show()
 
581
            messages.error('Edit link', '%s (%s)' % (ans,
 
582
                           panel.sorted[self.file_i]))
 
583
    panel.refresh_panel(panel)
 
584
    panel.refresh_panel(app.get_otherpanel())
 
585
 
 
586
 
 
587
def open_shell(panel):
 
588
    curses.endwin()
 
589
    os.system('cd \"%s\"; %s' % (panel.path,
 
590
                                 app.prefs.progs['shell']))
 
591
    curses.curs_set(0)
 
592
    panel.refresh_panel(panel)
 
593
    panel.refresh_panel(app.get_otherpanel())
 
594
 
 
595
 
 
596
# main functions
 
597
def view_file(panel):
 
598
    do_view_file(panel)
 
599
 
 
600
 
 
601
def edit_file(panel):
 
602
    do_edit_file(panel)
 
603
 
 
604
 
 
605
def copy(panel):
 
606
    otherpanel = app.get_otherpanel()
 
607
    destdir = otherpanel.path + os.sep
 
608
    if len(panel.selections):
 
609
        buf = 'Copy %d items to' % len(panel.selections)
 
610
        destdir = doEntry('Copy', buf, destdir)
 
611
        if destdir:
 
612
            overwrite_all = 0
 
613
            for f in panel.selections:
 
614
                if not overwrite_all:
 
615
                    if app.prefs.confirmations['overwrite']:
 
616
                        ans = run_thread(app, 'Copying \'%s\'' % f,
 
617
                                         files.copy,
 
618
                                         panel.path, f, destdir)
 
619
                        if type(ans) == type(''):
 
620
                            app.show()
 
621
                            ans2 = messages.confirm_all('Copy', 'Overwrite \'%s\'' % ans, 1)
 
622
                            if ans2 == -1:
 
623
                                break
 
624
                            elif ans2 == 2:
 
625
                                overwrite_all = 1
 
626
                            if ans2 != 0:
 
627
                                ans = run_thread(app, 'Copying \'%s\'' % f,
 
628
                                                 files.copy,
 
629
                                                 panel.path, f,
 
630
                                                 destdir, 0)
 
631
                            else:
 
632
                                continue
 
633
                    else:
 
634
                        ans = run_thread(app, 'Copying \'%s\'' % f,
 
635
                                         files.copy,
 
636
                                         panel.path, f, destdir, 0)
 
637
                else:
 
638
                    ans = run_thread(app, 'Copying \'%s\'' % f, files.copy,
 
639
                                     panel.path, f, destdir, 0)
 
640
                if ans and ans != -100:
 
641
                    for p in app.panels:
 
642
                        p.show()
 
643
                    messages.error('Copy \'%s\'' % f, '%s (%s)' % ans)
 
644
            panel.selections = []
 
645
        else:
 
646
            return
 
647
    else:
 
648
        filename = panel.sorted[panel.file_i]
 
649
        if filename == os.pardir:
 
650
            return
 
651
        buf = 'Copy \'%s\' to' % filename
 
652
        destdir = doEntry('Copy', buf, destdir)
 
653
        if destdir:
 
654
            if app.prefs.confirmations['overwrite']:
 
655
                ans = run_thread(app, 'Copying \'%s\'' % filename,
 
656
                                 files.copy,
 
657
                                 panel.path, filename, destdir)
 
658
                if type(ans) == type(''):
 
659
                    app.show()
 
660
                    ans2 = messages.confirm('Copy',
 
661
                                            'Overwrite \'%s\'' %
 
662
                                            ans, 1)
 
663
                    if ans2 != 0 and ans2 != -1:
 
664
                        ans = run_thread(app, 'Copying \'%s\'' % filename,
 
665
                                         files.copy,
 
666
                                         panel.path, filename, destdir, 0)
 
667
                    else:
 
668
                        return
 
669
            else:
 
670
                ans = run_thread(app, 'Copying \'%s\'' % filename,
 
671
                                 files.copy,
 
672
                                 panel.path, filename, destdir, 0)
 
673
            if ans and ans != -100:
 
674
                for p in app.panels:
 
675
                    p.show()
 
676
                messages.error('Copy \'%s\'' % filename,
 
677
                               '%s (%s)' % ans)
 
678
        else:
 
679
            return
 
680
    panel.refresh_panel(panel)
 
681
    panel.refresh_panel(otherpanel)
 
682
 
 
683
 
 
684
def move(panel):
 
685
    otherpanel = app.get_otherpanel()
 
686
    destdir = otherpanel.path + os.sep
 
687
    if len(panel.selections):
 
688
        buf = 'Move %d items to' % len(panel.selections)
 
689
        destdir = doEntry('Move', buf, destdir)
 
690
        if destdir:
 
691
            overwrite_all = 0
 
692
            for f in panel.selections:
 
693
                if not overwrite_all:
 
694
                    if app.prefs.confirmations['overwrite']:
 
695
                        ans = run_thread(app, 'Moving \'%s\'' % f,
 
696
                                         files.move,
 
697
                                         panel.path, f, destdir)
 
698
                        if type(ans) == type(''):
 
699
                            app.show()
 
700
                            ans2 = messages.confirm_all('Move', 'Overwrite \'%s\'' % ans, 1)
 
701
                            if ans2 == -1:
 
702
                                break
 
703
                            elif ans2 == 2:
 
704
                                overwrite_all = 1
 
705
                            if ans2 != 0:
 
706
                                ans = run_thread(app, 'Moving \'%s\'' % f,
 
707
                                                 files.move,
 
708
                                                 panel.path, f,
 
709
                                                 destdir, 0)
 
710
                            else:
 
711
                                continue
 
712
                    else:
 
713
                        ans = run_thread(app, 'Moving \'%s\'' % f,
 
714
                                         files.move,
 
715
                                         panel.path, f, destdir, 0)
 
716
                else:
 
717
                    ans = run_thread(app, 'Moving \'%s\'' % f, files.move,
 
718
                                     panel.path, f, destdir, 0)
 
719
                if ans and ans != -100:
 
720
                    for p in app.panels:
 
721
                        p.show()
 
722
                    messages.error('Move \'%s\'' % f, '%s (%s)' % ans)
 
723
            panel.selections = []
 
724
        else:
 
725
            return
 
726
    else:
 
727
        filename = panel.sorted[panel.file_i]
 
728
        if filename == os.pardir:
 
729
            return
 
730
        buf = 'Move \'%s\' to' % filename
 
731
        destdir = doEntry('Move', buf, destdir)
 
732
        if destdir:
 
733
            if app.prefs.confirmations['overwrite']:
 
734
                ans = run_thread(app, 'Moving \'%s\'' % filename,
 
735
                                 files.move,
 
736
                                 panel.path, filename, destdir)
 
737
                if type(ans) == type(''):
 
738
                    app.show()
 
739
                    ans2 = messages.confirm('Move',
 
740
                                            'Overwrite \'%s\'' %
 
741
                                            ans, 1)
 
742
                    if ans2 != 0 and ans2 != -1:
 
743
                        ans = run_thread(app, 'Moving \'%s\'' % filename,
 
744
                                         files.move,
 
745
                                         panel.path, filename, destdir, 0)
 
746
                    else:
 
747
                        return
 
748
            else:
 
749
                ans = run_thread(app, 'Moving \'%s\'' % filename,
 
750
                                 files.move,
 
751
                                 panel.path, filename, destdir, 0)
 
752
            if ans and ans != -100:
 
753
                for p in app.panels:
 
754
                    p.show()
 
755
                messages.error('Move \'%s\'' % filename,
 
756
                               '%s (%s)' % ans)
 
757
                ans = files.move(panel.path, filename, destdir, 0)
 
758
        else:
 
759
            return
 
760
    file_i_old = panel.file_i
 
761
    pvfs, base, vbase = panel.vfs, panel.base, panel.vbase
 
762
    panel.init_dir(panel.path)
 
763
    panel.vfs, panel.base, panel.vbase = pvfs, base, vbase
 
764
    if file_i_old > panel.nfiles:
 
765
        panel.file_i = panel.nfiles
 
766
    else:
 
767
        panel.file_i = file_i_old
 
768
    panel.fix_limits()
 
769
    panel.refresh_panel(panel)
 
770
    panel.refresh_panel(otherpanel)
 
771
 
 
772
 
 
773
def rename(panel):
 
774
    if len(panel.selections):
 
775
        fs = panel.selections[:]
 
776
    else:
 
777
        fs = [(panel.sorted[panel.file_i])]
 
778
    for filename in fs:
 
779
        app.show()
 
780
        if filename == os.pardir:
 
781
            continue
 
782
        buf = 'Rename \'%s\' to' % filename
 
783
        newname = doEntry('Rename', buf, filename)
 
784
        if newname:
 
785
            if app.prefs.confirmations['overwrite']:
 
786
                ans = run_thread(app, 'Renaming \'%s\'' % filename,
 
787
                                 files.move,
 
788
                                 panel.path, filename, newname)
 
789
                if type(ans) == type(''):
 
790
                    app.show()
 
791
                    ans2 = messages.confirm('Rename',
 
792
                                            'Overwrite \'%s\'' %
 
793
                                            ans, 1)
 
794
                    if ans2 != 0 and ans2 != -1:
 
795
                        ans = run_thread(app, 'Renaming \'%s\'' % filename,
 
796
                                         files.move,
 
797
                                         panel.path, filename, newname, 0)
 
798
                    else:
 
799
                        continue
 
800
            else:
 
801
                ans = run_thread(app, 'Renaming \'%s\'' % filename,
 
802
                                 files.move,
 
803
                                 panel.path, filename, newname, 0)
 
804
            if ans and ans != -100:
 
805
                for p in app.panels:
 
806
                    p.show()
 
807
                messages.error('Rename \'%s\'' % filename,
 
808
                               '%s (%s)' % ans)
 
809
                ans = files.move(panel.path, filename, newname, 0)
 
810
        else:
 
811
            continue
 
812
    file_i_old = panel.file_i
 
813
    pvfs, base, vbase = panel.vfs, panel.base, panel.vbase
 
814
    panel.init_dir(panel.path)
 
815
    panel.vfs, panel.base, panel.vbase = pvfs, base, vbase
 
816
    if file_i_old > panel.nfiles:
 
817
        panel.file_i = panel.nfiles
 
818
    else:
 
819
        panel.file_i = file_i_old
 
820
    panel.fix_limits()
 
821
    panel.refresh_panel(panel)
 
822
    panel.refresh_panel(app.get_otherpanel())
 
823
 
 
824
 
 
825
def make_dir(panel):
 
826
    newdir = doEntry('Make directory', 'Type directory name')
 
827
    if newdir == None or newdir == "":
 
828
        return
 
829
    ans = files.mkdir(panel.path, newdir)
 
830
    if ans:
 
831
        for p in app.panels:
 
832
            p.show()
 
833
        messages.error('Make directory',
 
834
                       '%s (%s)' % (ans, newdir))
 
835
        return
 
836
    panel.refresh_panel(panel)
 
837
    panel.refresh_panel(app.get_otherpanel())
 
838
 
 
839
 
 
840
def delete(panel):
 
841
    if len(panel.selections):
 
842
        delete_all = 0
 
843
        for f in panel.selections:
 
844
            if f == os.pardir:
 
845
                continue
 
846
            buf = 'Delete \'%s\'' % f
 
847
            if app.prefs.confirmations['delete'] and not delete_all:
 
848
                ans2 = messages.confirm_all('Delete', buf, 1)
 
849
                if ans2 == -1:
 
850
                    break
 
851
                elif ans2 == 2:
 
852
                    delete_all = 1
 
853
                if ans2 != 0:
 
854
                    ans = run_thread(app, 'Deleting \'%s\'' % f,
 
855
                                     files.delete, panel.path, f)
 
856
                else:
 
857
                    continue
 
858
            else:
 
859
                ans = run_thread(app, 'Deleting \'%s\'' % f,
 
860
                                 files.delete, panel.path, f)
 
861
            if ans and ans != -100:
 
862
                for p in app.panels:
 
863
                    p.show()
 
864
                messages.error('Delete \'%s\'' % f, '%s (%s)' % ans)
 
865
            else:
 
866
                continue
 
867
        file_i_old = panel.file_i
 
868
        file_old = panel.sorted[panel.file_i]
 
869
        pvfs, base, vbase = panel.vfs, panel.base, panel.vbase
 
870
        panel.init_dir(panel.path)
 
871
        panel.vfs, panel.base, panel.vbase = pvfs, base, vbase
 
872
        try:
 
873
            panel.file_i = panel.sorted.index(file_old)
 
874
        except ValueError:
 
875
            panel.file_i = file_i_old
 
876
    else:
 
877
        filename = panel.sorted[panel.file_i]
 
878
        if filename == os.pardir:
 
879
            return
 
880
        if app.prefs.confirmations['delete']:
 
881
            ans2 = messages.confirm('Delete', 'Delete \'%s\'' %
 
882
                                    filename, 1)
 
883
            if ans2 != 0 and ans2 != -1:
 
884
                ans = run_thread(app, 'Deleting \'%s\'' % filename,
 
885
                                 files.delete, panel.path, filename)
 
886
            else:
 
887
                return
 
888
        else:
 
889
            ans = run_thread(app, 'Deleting \'%s\'' % filename,
 
890
                             files.delete, panel.path, filename)
 
891
        if ans and ans != -100:
 
892
            for p in app.panels:
 
893
                p.show()
 
894
            messages.error('Delete \'%s\'' % filename, '%s (%s)' % ans)
 
895
        file_i_old = panel.file_i
 
896
        pvfs, base, vbase = panel.vfs, panel.base, panel.vbase
 
897
        panel.init_dir(panel.path)
 
898
        panel.vfs, panel.base, panel.vbase = pvfs, base, vbase
 
899
        if file_i_old > panel.nfiles:
 
900
            panel.file_i = panel.nfiles
 
901
        else:
 
902
            panel.file_i = file_i_old
 
903
    panel.fix_limits()
 
904
    panel.refresh_panel(app.get_otherpanel())
 
905
 
 
906
# menu
 
907
def show_help(panel):
 
908
    menu = [ 'r    Readme',
 
909
             'v    Readme pyview',
 
910
             'n    News',
 
911
             't    Todo',
 
912
             'c    ChangeLog',
 
913
             'l    License' ]
 
914
    cmd = messages.MenuWin('Help Menu', menu).run()
 
915
    if cmd == -1:
 
916
        return
 
917
    cmd = cmd[0]
 
918
    curses.endwin()
 
919
    docdir = os.path.join(sys.exec_prefix, 'share/doc/lfm')
 
920
    if cmd == 'r':
 
921
        fullfilename = os.path.join(docdir, 'README')
 
922
    elif cmd == 'v':
 
923
        fullfilename = os.path.join(docdir, 'README.pyview')
 
924
    elif cmd == 'n':
 
925
        fullfilename = os.path.join(docdir, 'NEWS')
 
926
    elif cmd == 't':
 
927
        fullfilename = os.path.join(docdir, 'TODO')
 
928
    elif cmd == 'c':
 
929
        fullfilename = os.path.join(docdir, 'ChangeLog')
 
930
    elif cmd == 'l':
 
931
        fullfilename = os.path.join(docdir, 'COPYING')
 
932
    os.system('%s \"%s\"' % (app.prefs.progs['pager'], fullfilename))
 
933
    curses.curs_set(0)
 
934
 
 
935
 
 
936
def file_menu(panel):
 
937
    menu = [ '@    Do something on file(s)',
 
938
             'i    File info',
 
939
             'p    Change file permissions, owner, group',
 
940
             'g    Gzip/gunzip file(s)',
 
941
             'b    Bzip2/bunzip2 file(s)',
 
942
             'x    Uncompress .tar.gz, .tar.bz2, .tar.Z, .zip',
 
943
             'u    Uncompress .tar.gz, etc in other panel',
 
944
             'c    Compress directory to .tar.gz',
 
945
             'd    Compress directory to .tar.bz2',
 
946
             'z    Compress directory to .zip' ]
 
947
    cmd = messages.MenuWin('File Menu', menu).run()
 
948
    if cmd == -1:
 
949
        return
 
950
    cmd = cmd[0]
 
951
    if cmd == '@':
 
952
        app.show()
 
953
        do_something_on_file(panel)
 
954
    elif cmd == 'i':
 
955
        do_show_file_info(panel)
 
956
    elif cmd == 'p':
 
957
        if panel.selections:
 
958
            app.show()
 
959
            i = 0
 
960
            change_all = 0
 
961
            for file in panel.selections:
 
962
                i += 1
 
963
                if not change_all:
 
964
                    ret = messages.ChangePerms(file, panel.files[file],
 
965
                                               app, i,
 
966
                                               len(panel.selections)).run()
 
967
                    if ret == -1:
 
968
                        break
 
969
                    elif ret == 0:
 
970
                        continue
 
971
                    elif ret[3] == 1:
 
972
                        change_all = 1                            
 
973
                filename = os.path.join(panel.path, file)
 
974
                ans = files.set_perms(filename, ret[0])
 
975
                if ans:
 
976
                    app.show()
 
977
                    messages.error('Chmod', '%s (%s)' % (ans, filename))
 
978
                ans = files.set_owner_group(filename, ret[1], ret[2])
 
979
                if ans:
 
980
                    app.show()
 
981
                    messages.error('Chown', '%s (%s)' % (ans, filename))
 
982
            panel.selections = []
 
983
        else:
 
984
            file = panel.sorted[panel.file_i]
 
985
            if file == os.pardir:
 
986
                return
 
987
            app.show()
 
988
            ret = messages.ChangePerms(file, panel.files[file],
 
989
                                       app).run()
 
990
            if ret == -1:
 
991
                return
 
992
            filename = os.path.join(panel.path, file)
 
993
            ans = files.set_perms(filename, ret[0])
 
994
            if ans:
 
995
                app.show()
 
996
                messages.error('Chmod', '%s (%s)' % (ans, filename))
 
997
            ans = files.set_owner_group(filename, ret[1], ret[2])
 
998
            if ans:
 
999
                app.show()
 
1000
                messages.error('Chown', '%s (%s)' % (ans, filename))
 
1001
        panel.refresh_panel(panel)
 
1002
        panel.refresh_panel(app.get_otherpanel())
 
1003
    elif cmd == 'g':
 
1004
        compress_uncompress_file(app, panel, 'gzip')
 
1005
        old_file = panel.sorted[panel.file_i]
 
1006
        panel.refresh_panel(panel)
 
1007
        panel.file_i = panel.sorted.index(old_file)
 
1008
        old_file = app.get_otherpanel().sorted[app.get_otherpanel().file_i]
 
1009
        panel.refresh_panel(app.get_otherpanel())
 
1010
        app.get_otherpanel().file_i = app.get_otherpanel().sorted.index(old_file)
 
1011
    elif cmd == 'b':
 
1012
        compress_uncompress_file(app, panel, 'bzip2')
 
1013
        old_file = panel.sorted[panel.file_i]
 
1014
        panel.refresh_panel(panel)
 
1015
        panel.file_i = panel.sorted.index(old_file)
 
1016
        old_file = app.get_otherpanel().sorted[app.get_otherpanel().file_i]
 
1017
        panel.refresh_panel(app.get_otherpanel())
 
1018
        app.get_otherpanel().file_i = app.get_otherpanel().sorted.index(old_file)
 
1019
    elif cmd == 'x':
 
1020
        uncompress_dir(app, panel, panel.path)
 
1021
        old_file = panel.sorted[panel.file_i]
 
1022
        panel.refresh_panel(panel)
 
1023
        panel.file_i = panel.sorted.index(old_file)
 
1024
        old_file = app.get_otherpanel().sorted[app.get_otherpanel().file_i]
 
1025
        panel.refresh_panel(app.get_otherpanel())
 
1026
        app.get_otherpanel().file_i = app.get_otherpanel().sorted.index(old_file)
 
1027
    elif cmd == 'u':
 
1028
        otherpath = app.get_otherpanel().path
 
1029
        uncompress_dir(app, panel, otherpath)
 
1030
        old_file = panel.sorted[panel.file_i]
 
1031
        panel.refresh_panel(panel)
 
1032
        panel.file_i = panel.sorted.index(old_file)
 
1033
        old_file = app.get_otherpanel().sorted[app.get_otherpanel().file_i]
 
1034
        panel.refresh_panel(app.get_otherpanel())
 
1035
        app.get_otherpanel().file_i = app.get_otherpanel().sorted.index(old_file)
 
1036
    elif cmd == 'c':
 
1037
        compress_dir(app, panel, 'gzip')
 
1038
        old_file = panel.sorted[panel.file_i]
 
1039
        panel.refresh_panel(panel)
 
1040
        panel.file_i = panel.sorted.index(old_file)
 
1041
        old_file = app.get_otherpanel().sorted[app.get_otherpanel().file_i]
 
1042
        panel.refresh_panel(app.get_otherpanel())
 
1043
        app.get_otherpanel().file_i = app.get_otherpanel().sorted.index(old_file)
 
1044
    elif cmd == 'd':
 
1045
        compress_dir(app, panel, 'bzip2')
 
1046
        old_file = panel.sorted[panel.file_i]
 
1047
        panel.refresh_panel(panel)
 
1048
        panel.file_i = panel.sorted.index(old_file)
 
1049
        old_file = app.get_otherpanel().sorted[app.get_otherpanel().file_i]
 
1050
        panel.refresh_panel(app.get_otherpanel())
 
1051
        app.get_otherpanel().file_i = app.get_otherpanel().sorted.index(old_file)
 
1052
    elif cmd == 'z':
 
1053
        compress_dir(app, panel, 'zip')
 
1054
        old_file = panel.sorted[panel.file_i]
 
1055
        panel.refresh_panel(panel)
 
1056
        panel.file_i = panel.sorted.index(old_file)
 
1057
        old_file = app.get_otherpanel().sorted[app.get_otherpanel().file_i]
 
1058
        panel.refresh_panel(app.get_otherpanel())
 
1059
        app.get_otherpanel().file_i = app.get_otherpanel().sorted.index(old_file)
 
1060
 
 
1061
 
 
1062
def general_menu(panel):
 
1063
    menu = [ '/    Find/grep file(s)',
 
1064
             '#    Show directories size',
 
1065
             's    Sort files',
 
1066
             't    Tree',
 
1067
             'f    Show filesystems info',
 
1068
             'o    Open shell',
 
1069
             'c    Edit configuration',
 
1070
             'a    Save configuration' ]
 
1071
    cmd = messages.MenuWin('General Menu', menu).run()
 
1072
    if cmd == -1:
 
1073
        return
 
1074
    cmd = cmd[0]
 
1075
    if cmd == '/':
 
1076
        app.show()
 
1077
        findgrep(panel)
 
1078
    elif cmd == '#':
 
1079
        show_dirs_size(panel)
 
1080
    elif cmd == 's':
 
1081
        app.show()
 
1082
        sort(panel)
 
1083
    elif cmd == 't':
 
1084
        if panel.vfs:
 
1085
            return
 
1086
        panel_i = app.panel
 
1087
        app.panel = not panel_i
 
1088
        panel.show()
 
1089
        t = Tree(panel.path, panel.pos)
 
1090
        ans = t.run()
 
1091
        del(t)
 
1092
        app.panel = panel_i
 
1093
        if ans != -1:
 
1094
            panel.init_dir(ans)
 
1095
            panel.fix_limits()
 
1096
    elif cmd == 'f':
 
1097
        do_show_fs_info()
 
1098
    elif cmd == 'o':
 
1099
        curses.endwin()
 
1100
        os.system('cd \"%s\"; %s' % (panel.path,
 
1101
                                     app.prefs.progs['shell']))
 
1102
        curses.curs_set(0)
 
1103
        panel.refresh_panel(panel)
 
1104
        panel.refresh_panel(app.get_otherpanel())
 
1105
    elif cmd == 'c':
 
1106
        app.prefs.edit(app)
 
1107
        app.prefs.load()
 
1108
    elif cmd == 'a':
 
1109
        app.prefs.save()
 
1110
 
 
1111
 
 
1112
 
 
1113
# window resize
 
1114
def resize_window(panel):
 
1115
    app.resize()
 
1116
    
 
1117
 
 
1118
# exit
 
1119
def quit(panel):
 
1120
    if app.prefs.confirmations['quit']:
 
1121
        ans = messages.confirm('Last File Manager',
 
1122
                               'Quit Last File Manager', 1)
 
1123
        if ans == 1:
 
1124
            return -1
 
1125
    else:
 
1126
        return -1
 
1127
 
 
1128
def exit(panel):  
 
1129
    if app.prefs.confirmations['quit']:
 
1130
        ans = messages.confirm('Last File Manager',
 
1131
                               'Quit Last File Manager', 1)
 
1132
        if ans == 1:
 
1133
            return -2
 
1134
    else:
 
1135
        return -2
 
1136
 
 
1137
 
 
1138
##################################################
 
1139
##### Utils
 
1140
##################################################
 
1141
# bookmarks
 
1142
def goto_bookmark(panel, num):
 
1143
    todir = app.prefs.bookmarks[num]
 
1144
    if panel.vfs:
 
1145
        vfs.exit(app, panel)
 
1146
    panel.init_dir(todir)
 
1147
    panel.fix_limits()
 
1148
 
 
1149
 
 
1150
# show size
 
1151
def show_dirs_size(panel):
 
1152
    if panel.selections:
 
1153
        for f in panel.selections:
 
1154
            if panel.files[f][files.FT_TYPE] != files.FTYPE_DIR and \
 
1155
               panel.files[f][files.FT_TYPE] != files.FTYPE_LNK2DIR:
 
1156
                continue
 
1157
            file = os.path.join(panel.path, f)
 
1158
            res = run_thread(app, 'Showing Directories Size',
 
1159
                             files.get_fileinfo, file, 0, 1)
 
1160
            if res == -100:
 
1161
                break
 
1162
            panel.files[f] = res
 
1163
                                               
 
1164
    else:
 
1165
        for f in panel.files.keys():
 
1166
            if f == os.pardir:
 
1167
                continue
 
1168
            if panel.files[f][files.FT_TYPE] != files.FTYPE_DIR and \
 
1169
               panel.files[f][files.FT_TYPE] != files.FTYPE_LNK2DIR:
 
1170
                continue
 
1171
            file = os.path.join(panel.path, f)
 
1172
            res = run_thread(app, 'Showing Directories Size',
 
1173
                             files.get_fileinfo, file, 0, 1)
 
1174
            if res == -100:
 
1175
                break
 
1176
            panel.files[f] = res
 
1177
 
 
1178
 
 
1179
# sort
 
1180
def sort(panel):
 
1181
    while 1:
 
1182
        ch = messages.get_a_key('Sorting mode',
 
1183
                                'N(o), by (n)ame, by (s)ize, by (d)ate,\nuppercase if reversed order, Ctrl-C to quit')
 
1184
        if ch in [ord('o'), ord('O')]:
 
1185
            app.modes['sort'] = files.SORTTYPE_None
 
1186
            break
 
1187
        elif ch in [ord('n')]:
 
1188
            app.modes['sort'] =  files.SORTTYPE_byName
 
1189
            break
 
1190
        elif ch in [ord('N')]:
 
1191
            app.modes['sort'] =  files.SORTTYPE_byName_rev
 
1192
            break
 
1193
        elif ch in [ord('s')]:
 
1194
            app.modes['sort'] = files.SORTTYPE_bySize
 
1195
            break
 
1196
        elif ch in [ord('S')]:
 
1197
            app.modes['sort'] = files.SORTTYPE_bySize_rev
 
1198
            break
 
1199
        elif ch in [ord('d')]:
 
1200
            app.modes['sort'] = files.SORTTYPE_byDate
 
1201
            break
 
1202
        elif ch in [ord('D')]:
 
1203
            app.modes['sort'] = files.SORTTYPE_byDate_rev
 
1204
            break
 
1205
        elif ch == -1:                 # Ctrl-C
 
1206
            break
 
1207
    old_filename = panel.sorted[panel.file_i]
 
1208
    old_selections = panel.selections[:]
 
1209
    panel.init_dir(panel.path)
 
1210
    panel.file_i = panel.sorted.index(old_filename)
 
1211
    panel.selections = old_selections
 
1212
    panel.fix_limits()
 
1213
 
 
1214
# do special view file
 
1215
def do_special_view_file(panel):
 
1216
    fullfilename = os.path.join(panel.path, panel.sorted[panel.file_i])
 
1217
    ext = os.path.splitext(fullfilename)[1].lower()[1:]
 
1218
    for typ, exts in app.prefs.filetypes.items():
 
1219
        if ext in exts:
 
1220
            prog = app.prefs.progs[typ]
 
1221
            if prog == '':
 
1222
                messages.error('Can\'t run program',
 
1223
                               'Can\'t start %s files, defaulting to view' % typ)
 
1224
                do_view_file(panel)
 
1225
                break
 
1226
            sys.stdout = sys.stderr = '/dev/null'
 
1227
            curses.endwin()
 
1228
            if app.prefs.options['detach_terminal_at_exec']:
 
1229
                pid = os.fork()
 
1230
                if pid == 0:
 
1231
                    os.setsid()
 
1232
                    sys.stdout = sys.stderr = '/dev/null'
 
1233
                    args = [prog]
 
1234
                    args.append(fullfilename)
 
1235
                    pid2 = os.fork()
 
1236
                    if pid2 == 0:
 
1237
                        os.chdir('/')
 
1238
                        # FIXME: catch errors
 
1239
                        try:
 
1240
                            os.execvp(args[0], args)
 
1241
                        except OSError:
 
1242
                            os._exit(-1)
 
1243
                    else:
 
1244
                        os._exit(0)
 
1245
                else:
 
1246
                    curses.curs_set(0)
 
1247
                    sys.stdout = sys.__stdout__
 
1248
                    sys.stderr = sys.__stderr__
 
1249
                    break
 
1250
            else:
 
1251
                # programs inside same terminal as lfm should use:
 
1252
                os.system('%s \"%s\"' % (prog, fullfilename))
 
1253
                curses.curs_set(0)
 
1254
                sys.stdout = sys.__stdout__
 
1255
                sys.stderr = sys.__stderr__
 
1256
                break
 
1257
    else:
 
1258
        do_view_file(panel)
 
1259
    panel.refresh_panel(panel)
 
1260
    panel.refresh_panel(app.get_otherpanel())
 
1261
 
 
1262
 
 
1263
# do view file
 
1264
def do_view_file(panel):
 
1265
    fullfilename = os.path.join(panel.path, panel.sorted[panel.file_i])
 
1266
    curses.endwin()
 
1267
    os.system('%s \"%s\"' % (app.prefs.progs['pager'], fullfilename))
 
1268
    curses.curs_set(0)
 
1269
 
 
1270
 
 
1271
# do edit file
 
1272
def do_edit_file(panel):
 
1273
    curses.endwin()
 
1274
    fullfilename = os.path.join(panel.path, panel.sorted[panel.file_i])
 
1275
    os.system('%s \"%s\"' % (app.prefs.progs['editor'], fullfilename))
 
1276
    curses.curs_set(0)
 
1277
    panel.refresh_panel(panel)
 
1278
    panel.refresh_panel(app.get_otherpanel())
 
1279
 
 
1280
 
 
1281
# do execute file
 
1282
def do_do_execute_file(path, cmd):
 
1283
    i, a = os.popen4('cd \"%s\"; \"%s\"; echo ZZENDZZ' % (path, cmd))
 
1284
    output = ''
 
1285
    while 1:
 
1286
        buf = a.readline()[:-1]
 
1287
        if buf == 'ZZENDZZ':
 
1288
            break
 
1289
        elif buf:
 
1290
            output += buf + '\n'
 
1291
    i.close(); a.close()
 
1292
    return output
 
1293
 
 
1294
 
 
1295
def do_execute_file(panel):
 
1296
    fullfilename = os.path.join(panel.path, panel.sorted[panel.file_i])
 
1297
    parms = doEntry('Execute file', 'Enter arguments')
 
1298
    if parms == None:
 
1299
        return
 
1300
    elif parms == '':
 
1301
        cmd = '%s' % fullfilename
 
1302
    else:                
 
1303
        cmd = '%s %s' % (fullfilename, parms)
 
1304
    curses.endwin()
 
1305
    err = run_thread(app, 'Executing \"%s\"' % cmd,
 
1306
                     do_do_execute_file, panel.path, cmd)
 
1307
    if err and err != -100:
 
1308
        if app.prefs.options['show_output_after_exec']:
 
1309
            curses.curs_set(0)
 
1310
            for panel in app.panels:
 
1311
                panel.show()
 
1312
            if messages.confirm('Executing file(s)', 'Show output'):
 
1313
                lst = [(l, 2) for l in err.split('\n')]
 
1314
                pyview.InternalView('Output of \"%s\"' % cmd,
 
1315
                                    lst, center = 0).run()
 
1316
    curses.curs_set(0)
 
1317
    panel.refresh_panel(panel)
 
1318
    panel.refresh_panel(app.get_otherpanel())
 
1319
 
 
1320
 
 
1321
# do something on file
 
1322
### do_something_on_file does not have to run inside run_thread, either capture
 
1323
### the output because it makes not possible to exec commands such as 'less', etc.
 
1324
# def do_do_something_on_file(panel, cmd, filename):
 
1325
#     i, a = os.popen4('cd \"%s\"; %s \"%s\"; echo ZZENDZZ' %
 
1326
#                      (panel.path, cmd, filename))
 
1327
#     output = ''
 
1328
#     while 1:
 
1329
#         buf = a.readline()[:-1]
 
1330
#         if buf == 'ZZENDZZ':
 
1331
#             break
 
1332
#         elif buf:
 
1333
#             output += buf + '\n'
 
1334
#     i.close(); a.close()
 
1335
#     return output
 
1336
 
 
1337
 
 
1338
# def do_something_on_file(panel):
 
1339
#     cmd = doEntry('Do something on file(s)', 'Enter command')
 
1340
#     if cmd:
 
1341
#         curses.endwin()
 
1342
#         if len(panel.selections):
 
1343
#             for f in panel.selections:
 
1344
#                 err = run_thread('Executing \"%s %s\"' % (cmd, f),
 
1345
#                                  do_do_something_on_file, panel, cmd, f)
 
1346
#                 if err and err != -100:
 
1347
#                     if app.prefs.options['show_output_after_exec']:
 
1348
#                         curses.curs_set(0)
 
1349
#                         for panel in app.panels:
 
1350
#                             panel.show()
 
1351
#                         if messages.confirm('Do something on file(s)',
 
1352
#                                             'Show output'):
 
1353
#                             lst = [(l, 2) for l in err.split('\n')]
 
1354
#                             pyview.InternalView('Output of \"%s %s\"' %
 
1355
#                                                 (cmd, f),
 
1356
#                                                 lst, center = 0).run()
 
1357
#             panel.selections = []
 
1358
#         else:
 
1359
#             filename = panel.sorted[panel.file_i]
 
1360
#             err = run_thread('Executing \"%s %s\"' % (cmd, filename),
 
1361
#                              do_do_something_on_file, panel, cmd, filename)
 
1362
#             if err and err != -100:
 
1363
#                 if app.prefs.options['show_output_after_exec']:
 
1364
#                     curses.curs_set(0)
 
1365
#                     for panel in app.panels:
 
1366
#                         panel.show()
 
1367
#                     if messages.confirm('Do something on file(s)', 'Show output'):
 
1368
#                         lst = [(l, 2) for l in err.split('\n')]
 
1369
#                         pyview.InternalView('Output of \"%s %s\"' %
 
1370
#                                             (cmd, filename),
 
1371
#                                             lst, center = 0).run()
 
1372
#         curses.curs_set(0)
 
1373
#         panel.refresh_panel(panel)
 
1374
#         panel.refresh_panel(app.get_otherpanel())
 
1375
 
 
1376
def do_something_on_file(panel):
 
1377
    cmd = doEntry('Do something on file(s)', 'Enter command')
 
1378
    if cmd:
 
1379
        curses.endwin()
 
1380
        if len(panel.selections):
 
1381
            for f in panel.selections:
 
1382
                os.system('cd \"%s\"; %s \"%s\"' % (panel.path, cmd, f))
 
1383
            panel.selections = []
 
1384
        else:
 
1385
            os.system('cd \"%s\"; %s \"%s\"' %
 
1386
                      (panel.path, cmd, panel.sorted[panel.file_i]))
 
1387
        curses.curs_set(0)
 
1388
        panel.refresh_panel(panel)
 
1389
        panel.refresh_panel(app.get_otherpanel())
 
1390
 
 
1391
 
 
1392
# show file info
 
1393
def do_show_file_info(panel):
 
1394
    def show_info(panel, file):
 
1395
        import stat
 
1396
        from time import ctime
 
1397
 
 
1398
        fullfilename = os.path.join(panel.path, file)
 
1399
        file_data = panel.files[file]
 
1400
        file_data2 = os.lstat(fullfilename)
 
1401
        buf = []
 
1402
        user = os.environ['USER']
 
1403
        username = files.get_user_fullname(user)
 
1404
        so, host, ver, tmp, arch = os.uname()
 
1405
        buf.append(('%s v%s executed by %s' % (LFM_NAME, VERSION, username), 5))
 
1406
        buf.append(('<%s@%s> on a %s %s [%s]' % (user, host, so, ver, arch), 5))
 
1407
        buf.append(('', 2))
 
1408
        fileinfo = os.popen('file \"%s\"' % \
 
1409
                            fullfilename).read().split(':')[1].strip()
 
1410
        buf.append(('%s: %s (%s)' % (files.FILETYPES[file_data[0]][1], file,
 
1411
                                     fileinfo), 6))
 
1412
        if not panel.vfs:
 
1413
            path = panel.path
 
1414
        else:
 
1415
            path = vfs.join(app, panel) + ' [%s]' % panel.base
 
1416
        buf.append(('Path: %s' % path[-(curses.COLS-8):], 6))
 
1417
        buf.append(('Size: %s bytes' % file_data[files.FT_SIZE], 6))
 
1418
        buf.append(('Mode: %s (%4.4o)' % \
 
1419
                    (files.perms2str(file_data[files.FT_PERMS]),
 
1420
                     file_data[files.FT_PERMS]), 6))
 
1421
        buf.append(('Links: %s' % file_data2[stat.ST_NLINK], 6))
 
1422
        buf.append(('User ID: %s (%s) / Group ID: %s (%s)' % \
 
1423
                    (file_data[files.FT_OWNER], file_data2[stat.ST_UID],
 
1424
                     file_data[files.FT_GROUP], file_data2[stat.ST_GID]), 6))
 
1425
        buf.append(('Last access: %s' % ctime(file_data2[stat.ST_ATIME]), 6))
 
1426
        buf.append(('Last modification: %s' % ctime(file_data2[stat.ST_MTIME]), 6))
 
1427
        buf.append(('Last change: %s' % ctime(file_data2[stat.ST_CTIME]), 6))
 
1428
        buf.append(('Location: %d, %d / Inode: #%X (%Xh:%Xh)' % \
 
1429
                    ((file_data2[stat.ST_DEV] >> 8) & 0x00FF,
 
1430
                    file_data2[stat.ST_DEV] & 0x00FF,
 
1431
                    file_data2[stat.ST_INO], file_data2[stat.ST_DEV],
 
1432
                    file_data2[stat.ST_INO]), 6))
 
1433
        fss = files.get_fs_info()
 
1434
        fs = ['/dev', '0', '0', '0', '0%', '/', 'unknown']
 
1435
        for e in fss:
 
1436
            if fullfilename.find(e[5]) != -1 and (len(e[5]) > len(fs[5]) or e[5] == os.sep):
 
1437
                fs = e
 
1438
        buf.append(('File system: %s on %s (%s) %d%% free' % \
 
1439
                    (fs[0], fs[5], fs[6], 100 - int(fs[4][:-1])), 6))
 
1440
        pyview.InternalView('Information about \'%s\'' % file, buf).run()
 
1441
 
 
1442
    if panel.selections:
 
1443
        for f in panel.selections:
 
1444
            show_info(panel, f)
 
1445
        panel.selections = []
 
1446
    else:
 
1447
        show_info(panel, panel.sorted[panel.file_i])
 
1448
 
 
1449
 
 
1450
# do show filesystems info
 
1451
def do_show_fs_info():
 
1452
    """Show file systems info"""
 
1453
 
 
1454
    fs = files.get_fs_info()
 
1455
    if type(fs) != type([]):
 
1456
        app.show()
 
1457
        messages.error('Show filesystems info', fs)
 
1458
        return
 
1459
    app.show()
 
1460
    buf = []
 
1461
    buf.append(('Filesystem       FS type    Total Mb     Used   Avail.  Use%  Mount point', 6))
 
1462
    buf.append('-')
 
1463
    for l in fs:
 
1464
        buf.append(('%-15s  %-10s  %7s  %7s  %7s  %4s  %s' % \
 
1465
                    (l[0], l[6], l[1], l[2], l[3], l[4], l[5]), 2))
 
1466
    texts = [l[0] for l in buf]
 
1467
    buf[1] = ('-' * len(max(texts)), 6)
 
1468
    pyview.InternalView('Show filesystems info', buf).run()
 
1469
 
 
1470
 
 
1471
# find and grep
 
1472
def findgrep(panel):
 
1473
    fs, pat = doDoubleEntry('Find files', 'Filename', '*', 1, 1,
 
1474
                            'Content', '', 1, 0)
 
1475
    if fs == None or fs == '':
 
1476
        return
 
1477
    path = os.path.dirname(fs)
 
1478
    fs = os.path.basename(fs)
 
1479
    if path == None or path == '':
 
1480
        path = panel.path
 
1481
    if path[0] != os.sep:
 
1482
        path = os.path.join(panel.path, path)
 
1483
    if pat:
 
1484
        m = run_thread(app, 'Searching for \'%s\' in \"%s\" files' % (pat, fs),
 
1485
                       files.findgrep,
 
1486
                       path, fs, pat, app.prefs.progs['find'],
 
1487
                       app.prefs.progs['egrep'])
 
1488
        if not m:
 
1489
            app.show()
 
1490
            messages.error('Find/Grep', 'No files found')
 
1491
            return
 
1492
        elif m == -100:
 
1493
            return
 
1494
        elif m == -1:
 
1495
            app.show()
 
1496
            messages.error('Find/Grep', 'Error while creating pipe')
 
1497
            return
 
1498
    else:
 
1499
        m = run_thread(app, 'Searching for \"%s\" files' % fs, files.find,
 
1500
                       path, fs, app.prefs.progs['find'])
 
1501
        if not m:
 
1502
            app.show()
 
1503
            messages.error('Find', 'No files found')
 
1504
            return
 
1505
        elif m == -100:
 
1506
            return
 
1507
        elif m == -1:
 
1508
            app.show()
 
1509
            messages.error('Find', 'Error while creating pipe')
 
1510
            return        
 
1511
    find_quit = 0
 
1512
    par = ''
 
1513
    while not find_quit:
 
1514
        cmd, par = messages.FindfilesWin(m, par).run()
 
1515
        if par:
 
1516
            if pat:
 
1517
                try:
 
1518
                    line = int(par.split(':')[0])
 
1519
                except ValueError:
 
1520
                    line = 0
 
1521
                    f = os.path.join(path, par)
 
1522
                else:
 
1523
                    f = os.path.join(path, par[par.find(':')+1:])
 
1524
            else:
 
1525
                line = 0
 
1526
                f = os.path.join(path, par)
 
1527
            if os.path.isdir(f):
 
1528
                todir = f
 
1529
                tofile = None
 
1530
            else:
 
1531
                todir = os.path.dirname(f)
 
1532
                tofile = os.path.basename(f)
 
1533
        if cmd == 0:             # goto file
 
1534
            pvfs, base, vbase = panel.vfs, panel.base, panel.vbase
 
1535
            panel.init_dir(todir)
 
1536
            panel.vfs, panel.base, panel.vbase = pvfs, base, vbase
 
1537
            if tofile:
 
1538
                panel.file_i = panel.sorted.index(tofile)
 
1539
            panel.fix_limits()
 
1540
            find_quit = 1
 
1541
        elif cmd == 1:           # panelize
 
1542
            fs = []
 
1543
            for f in m:
 
1544
                if pat:
 
1545
                    f = f[f.find(':')+1:]
 
1546
                try:
 
1547
                    fs.index(f)
 
1548
                except ValueError:
 
1549
                    fs.append(f)
 
1550
                else:
 
1551
                    continue
 
1552
            vfs.pan_init(app, panel, fs)
 
1553
            find_quit = 1
 
1554
        elif cmd == 2:           # view
 
1555
            if tofile:
 
1556
                curses.curs_set(0)
 
1557
                curses.endwin()
 
1558
                os.system('%s +%d \"%s\"' %
 
1559
                          (app.prefs.progs['pager'], line, f))
 
1560
                curses.curs_set(0)
 
1561
            else:
 
1562
                messages.error('View', 'it\'s a directory',
 
1563
                               todir)
 
1564
        elif cmd == 3:           # edit
 
1565
            if tofile:
 
1566
                curses.endwin()
 
1567
                if line > 0:
 
1568
                    os.system('%s +%d \"%s\"' %
 
1569
                              (app.prefs.progs['editor'], line, f))
 
1570
                else:
 
1571
                    os.system('%s \"%s\"' %
 
1572
                              (app.prefs.progs['editor'], f))
 
1573
                curses.curs_set(0)
 
1574
                panel.refresh_panel(panel)
 
1575
                panel.refresh_panel(app.get_otherpanel())
 
1576
            else:
 
1577
                messages.error('Edit', 'it\'s a directory',
 
1578
                               todir)
 
1579
        elif cmd == 4:           # do something on file
 
1580
            cmd2 = doEntry('Do something on file',
 
1581
                           'Enter command')
 
1582
            if cmd2:
 
1583
                curses.endwin()
 
1584
                os.system('%s \"%s\"' % (cmd2, f))
 
1585
                curses.curs_set(0)
 
1586
                panel.refresh_panel(panel)
 
1587
                panel.refresh_panel(app.get_otherpanel())
 
1588
        else:
 
1589
            find_quit = 1
 
1590
 
 
1591
 
 
1592
 
 
1593
 
 
1594
 
 
1595
 
 
1596
#
 
1597
def doEntry(title, help, path = '', with_historic = 1, with_complete = 1):
 
1598
    panelpath = app.panels[app.panel].path
 
1599
    while 1:
 
1600
        path = messages.Entry(title, help, path, with_historic, with_complete,
 
1601
                              panelpath).run()
 
1602
        if type(path) != type([]):
 
1603
            return path
 
1604
        else:
 
1605
            app.show()
 
1606
            path = path.pop()
 
1607
 
 
1608
 
 
1609
def doDoubleEntry(title, help1, path1 = '', with_historic1 = 1, with_complete1 = 1,
 
1610
                  help2 = '', path2 = '', with_historic2 = 1, with_complete2 = 1):
 
1611
    active_entry = 0
 
1612
    panelpath1 = app.panels[app.panel].path
 
1613
    panelpath2 = app.panels[app.panel].path
 
1614
    while 1:
 
1615
        path = messages.DoubleEntry(title, help1, path1, with_historic1,
 
1616
                                    with_complete1, panelpath1,
 
1617
                                    help2, path2, with_historic2,
 
1618
                                    with_complete2, panelpath2,
 
1619
                                    active_entry).run()
 
1620
        if type(path) != type([]):
 
1621
            return path
 
1622
        else:
 
1623
            app.show()
 
1624
            active_entry = path.pop()
 
1625
            path2 = path.pop()
 
1626
            path1 = path.pop()
 
1627
 
 
1628
 
 
1629
##################################################
 
1630
##### Tree
 
1631
##################################################
 
1632
class Tree:
 
1633
    """Tree class"""
 
1634
 
 
1635
    def __init__(self, path = os.sep, panelpos = 0):
 
1636
        if not os.path.exists(path):
 
1637
            return None
 
1638
        self.__init_curses(panelpos)
 
1639
        if path[-1] == os.sep and path != os.sep:
 
1640
            path = path[:-1]
 
1641
        self.path = path
 
1642
        self.tree = self.get_tree()
 
1643
        self.pos = self.__get_curpos()
 
1644
 
 
1645
 
 
1646
    def __get_dirs(self, path):
 
1647
        """return a list of dirs in path"""
 
1648
        
 
1649
        ds = []
 
1650
        try:
 
1651
            for d in os.listdir(path):
 
1652
                if os.path.isdir(os.path.join(path, d)):
 
1653
                    ds.append(d)
 
1654
        except OSError:
 
1655
            pass
 
1656
        ds.sort()
 
1657
        return ds
 
1658
 
 
1659
 
 
1660
    def __get_graph(self, path):
 
1661
        """return 2 dicts with tree structure"""
 
1662
 
 
1663
        tree_n = {}
 
1664
        tree_dir = {}
 
1665
        expanded = None
 
1666
        while path:
 
1667
            if path == os.sep and tree_dir.has_key(os.sep):
 
1668
                break
 
1669
            tree_dir[path] = (self.__get_dirs(path), expanded)
 
1670
            expanded = os.path.basename(path)
 
1671
            path = os.path.dirname(path)
 
1672
        dir_keys = tree_dir.keys()
 
1673
        dir_keys.sort()
 
1674
        n = 0
 
1675
        for d in dir_keys:
 
1676
            tree_n[n] = d
 
1677
            n += 1
 
1678
        return tree_n, tree_dir
 
1679
 
 
1680
 
 
1681
    def __get_node(self, i, tn, td, base):
 
1682
        """expand branch"""
 
1683
 
 
1684
        lst2 = []
 
1685
        node = tn[i]
 
1686
        dirs, expanded_node = td[node]
 
1687
        if not expanded_node:
 
1688
            return []
 
1689
        for d in dirs:
 
1690
            if d == expanded_node:
 
1691
                lst2.append([d, i, os.path.join(base, d)])
 
1692
                lst3 = self.__get_node(i+1, tn, td, os.path.join(base, d))
 
1693
                if lst3 != None:
 
1694
                    lst2.extend(lst3)
 
1695
            else:
 
1696
                lst2.append([d, i, os.path.join(base, d)])
 
1697
        return lst2
 
1698
 
 
1699
 
 
1700
    def get_tree(self):
 
1701
        """return list with tree structure"""
 
1702
 
 
1703
        tn, td = self.__get_graph(self.path)
 
1704
        tree = [[os.sep, -1, os.sep]]
 
1705
        tree.extend(self.__get_node(0, tn, td, os.sep))
 
1706
        return tree
 
1707
        
 
1708
 
 
1709
    def __get_curpos(self):
 
1710
        """get position of current dir"""
 
1711
        
 
1712
        for i in range(len(self.tree)):
 
1713
            if self.path == self.tree[i][2]:
 
1714
                return i
 
1715
        else:
 
1716
            return -1
 
1717
 
 
1718
 
 
1719
    def regenerate_tree(self, newpos):
 
1720
        """regenerate tree when changing to a new directory"""
 
1721
        
 
1722
        self.path = self.tree[newpos][2]
 
1723
        self.tree = self.get_tree()
 
1724
        self.pos = self.__get_curpos()
 
1725
 
 
1726
 
 
1727
    def show_tree(self, a = 0, z = -1):
 
1728
        """show an ascii representation of the tree. Not used in lfm"""
 
1729
        
 
1730
        if z > len(self.tree) or z == -1:
 
1731
            z = len(self.tree)
 
1732
        for i in range(a, z):
 
1733
            name, depth, fullname = self.tree[i]
 
1734
            if fullname == self.path:
 
1735
                name += ' <====='
 
1736
            if name == os.sep:
 
1737
                print ' ' + name
 
1738
            else:
 
1739
                print ' | ' * depth + ' +- ' + name
 
1740
 
 
1741
 
 
1742
    # GUI functions
 
1743
    def __init_curses(self, pos):
 
1744
        """initialize curses stuff"""
 
1745
        
 
1746
        if pos == 0:      # not visible panel
 
1747
            self.dims = (curses.LINES-2, 0, 0, 0)     # h, w, y, x
 
1748
            return
 
1749
        elif pos == 1:    # left panel -> right
 
1750
            self.dims = (curses.LINES-2, int(curses.COLS/2), 1, int(curses.COLS/2))
 
1751
        elif pos == 2:    # right panel -> left
 
1752
            self.dims = (curses.LINES-2, int(curses.COLS/2), 1, 0)
 
1753
        else:             # full panel -> right
 
1754
            self.dims = (curses.LINES-2, int(curses.COLS/2), 1, int(curses.COLS/2))
 
1755
        try:
 
1756
            self.win_tree = curses.newwin(self.dims[0], self.dims[1], self.dims[2], self.dims[3])
 
1757
        except curses.error:
 
1758
            print 'Can\'t create tree window'
 
1759
            sys.exit(-1)
 
1760
        self.win_tree.keypad(1)
 
1761
        if curses.has_colors():
 
1762
            self.win_tree.attrset(curses.color_pair(2))
 
1763
            self.win_tree.bkgdset(curses.color_pair(2))
 
1764
 
 
1765
        
 
1766
    def show(self):
 
1767
        """show tree panel"""
 
1768
        
 
1769
        self.win_tree.erase()
 
1770
        h = curses.LINES - 4
 
1771
        n = len(self.tree)
 
1772
        # box
 
1773
        self.win_tree.attrset(curses.color_pair(5))
 
1774
        self.win_tree.box()
 
1775
        self.win_tree.addstr(0, 2, ' Tree ', curses.color_pair(6) | curses.A_BOLD)
 
1776
        # tree
 
1777
        self.win_tree.attrset(curses.color_pair(2))
 
1778
        j = 0
 
1779
        a, z = int(self.pos/h) * h, (int(self.pos/h) + 1) * h
 
1780
        if z > n:
 
1781
            z = n
 
1782
            a = z - h
 
1783
            if a < 0:
 
1784
                a = 0
 
1785
        for i in range(a, z):
 
1786
            j += 1
 
1787
            name, depth, fullname = self.tree[i]
 
1788
            if name == os.sep:
 
1789
                self.win_tree.addstr(j, 1, ' ')
 
1790
            else:
 
1791
                self.win_tree.move(j, 1)
 
1792
                for kk in range(depth):
 
1793
                    self.win_tree.addstr(' ')
 
1794
                    self.win_tree.addch(curses.ACS_VLINE)
 
1795
                    self.win_tree.addstr(' ')
 
1796
                self.win_tree.addstr(' ')
 
1797
                if i == n - 1:
 
1798
                    self.win_tree.addch(curses.ACS_LLCORNER)
 
1799
                elif depth > self.tree[i+1][1]:
 
1800
                    self.win_tree.addch(curses.ACS_LLCORNER)
 
1801
                else:
 
1802
                    self.win_tree.addch(curses.ACS_LTEE)
 
1803
                self.win_tree.addch(curses.ACS_HLINE)
 
1804
                self.win_tree.addstr(' ')
 
1805
            w = int(curses.COLS / 2) - 2
 
1806
            wd = 3 * depth + 4
 
1807
            if fullname == self.path:
 
1808
                self.win_tree.addstr(name[:w-wd-3], curses.color_pair(3))
 
1809
                child_dirs = self.__get_dirs(self.path)
 
1810
                if len(child_dirs) > 0:
 
1811
                    self.win_tree.addstr(' ')
 
1812
                    self.win_tree.addch(curses.ACS_HLINE)
 
1813
                    self.win_tree.addch(curses.ACS_RARROW)
 
1814
            else:
 
1815
                self.win_tree.addstr(name[:w-wd])
 
1816
        # scrollbar
 
1817
        if n > h:
 
1818
            nn = int(h * h / n)
 
1819
            if nn == 0:
 
1820
                nn = 1
 
1821
            aa = int(self.pos / h) * h
 
1822
            y0 = int(aa * h / n)
 
1823
            if y0 < 0:
 
1824
                y0 = 0
 
1825
            elif y0 + nn > h:
 
1826
                y0 = h - nn - 1
 
1827
        else:
 
1828
            y0 = 0
 
1829
            nn = 0
 
1830
        self.win_tree.attrset(curses.color_pair(5))
 
1831
        self.win_tree.vline(y0 + 2, int(curses.COLS/2) - 1, curses.ACS_CKBOARD, nn)
 
1832
        if a != 0:
 
1833
            self.win_tree.vline(1, int(curses.COLS/2) - 1, '^', 1)
 
1834
            if nn == 1 and (y0 + 2 == 2):
 
1835
                self.win_tree.vline(3, int(curses.COLS/2) - 1, curses.ACS_CKBOARD, nn)
 
1836
        if n - 1 > a + h - 1:
 
1837
            self.win_tree.vline(h, int(curses.COLS/2) - 1, 'v', 1)
 
1838
            if nn == 1 and (y0 + 2 == h + 1):
 
1839
                self.win_tree.vline(h, int(curses.COLS/2) - 1, curses.ACS_CKBOARD, nn)
 
1840
        # status
 
1841
        app.win_status.erase()
 
1842
        wp = curses.COLS - 8
 
1843
        if len(self.path) > wp:
 
1844
            path = self.path[:int(wp/2) -1] + '~' + self.path[-int(wp/2):]
 
1845
        else:
 
1846
            path = self.path
 
1847
        app.win_status.addstr(' Path: %s' % path)
 
1848
        app.win_status.refresh()
 
1849
 
 
1850
 
 
1851
    def run(self):
 
1852
        """manage keys"""
 
1853
        
 
1854
        while 1:
 
1855
            self.show()
 
1856
            chext = 0
 
1857
            ch = self.win_tree.getch()
 
1858
 
 
1859
            # to avoid extra chars input
 
1860
            if ch == 0x1B:
 
1861
                chext = 1
 
1862
                ch = self.win_tree.getch()
 
1863
                ch = self.win_tree.getch()
 
1864
 
 
1865
            # cursor up
 
1866
            if ch in [ord('p'), ord('P'), curses.KEY_UP]:
 
1867
                if self.pos == 0:
 
1868
                    continue
 
1869
                if self.tree[self.pos][1] != self.tree[self.pos-1][1]:
 
1870
                    continue
 
1871
                newpos = self.pos - 1
 
1872
            # cursor down
 
1873
            elif ch in [ord('n'), ord('N'), curses.KEY_DOWN]:
 
1874
                if self.pos == len(self.tree) - 1:
 
1875
                    continue
 
1876
                if self.tree[self.pos][1] != self.tree[self.pos+1][1]:
 
1877
                    continue
 
1878
                newpos = self.pos + 1
 
1879
            # page previous
 
1880
            elif ch in [curses.KEY_PPAGE, curses.KEY_BACKSPACE,
 
1881
                        0x08, 0x10]:                         # BackSpace, Ctrl-P
 
1882
                depth = self.tree[self.pos][1] 
 
1883
                if self.pos - (curses.LINES-4) >= 0:
 
1884
                    if depth  == self.tree[self.pos - (curses.LINES-4)][1]:
 
1885
                        newpos = self.pos - (curses.LINES-4)
 
1886
                    else:
 
1887
                        newpos = self.pos
 
1888
                        while 1:
 
1889
                            if newpos - 1 < 0:
 
1890
                                break
 
1891
                            if self.tree[newpos-1][1] != depth:
 
1892
                                break
 
1893
                            newpos -= 1
 
1894
                else:
 
1895
                    newpos = self.pos
 
1896
                    while 1:
 
1897
                        if newpos - 1 < 0:
 
1898
                            break
 
1899
                        if self.tree[newpos-1][1] != depth:
 
1900
                            break
 
1901
                        newpos -= 1
 
1902
            # page next
 
1903
            elif ch in [curses.KEY_NPAGE, ord(' '), 0x0E]:   # Ctrl-N
 
1904
                depth = self.tree[self.pos][1] 
 
1905
                if self.pos + (curses.LINES-4) <= len(self.tree) - 1:
 
1906
                    if depth  == self.tree[self.pos + (curses.LINES-4)][1]:
 
1907
                        newpos = self.pos + (curses.LINES-4)
 
1908
                    else:
 
1909
                        newpos = self.pos
 
1910
                        while 1:
 
1911
                            if newpos + 1 == len(self.tree):
 
1912
                                break
 
1913
                            if self.tree[newpos+1][1] != depth:
 
1914
                                break
 
1915
                            newpos += 1
 
1916
                else:
 
1917
                    newpos = self.pos
 
1918
                    while 1:
 
1919
                        if newpos + 1 == len(self.tree):
 
1920
                            break
 
1921
                        if self.tree[newpos+1][1] != depth:
 
1922
                            break
 
1923
                        newpos += 1
 
1924
            # home
 
1925
            elif (ch in [curses.KEY_HOME, 0x001,0x16A ]) or \
 
1926
                 (chext == 1) and (ch == 72):  # home
 
1927
                newpos = 1
 
1928
            # end
 
1929
            elif (ch in [curses.KEY_END, 0x005, 0x181]) or \
 
1930
                 (chext == 1) and (ch == 70):   # end
 
1931
                newpos = len(self.tree) - 1
 
1932
            # cursor left
 
1933
            elif ch in [curses.KEY_LEFT]:
 
1934
                if self.pos == 0:
 
1935
                    continue
 
1936
                newdepth = self.tree[self.pos][1] - 1
 
1937
                for i in range(self.pos-1, -1, -1):
 
1938
                    if self.tree[i][1] == newdepth:
 
1939
                        break
 
1940
                newpos = i
 
1941
            # cursor right
 
1942
            elif ch in [curses.KEY_RIGHT]:
 
1943
                child_dirs = self.__get_dirs(self.path)
 
1944
                if len(child_dirs) > 0:
 
1945
                    self.path = os.path.join(self.path, child_dirs[0])
 
1946
                    self.tree = self.get_tree()
 
1947
                    self.pos = self.__get_curpos()
 
1948
                continue                   
 
1949
            # enter
 
1950
            elif ch in [10, 13]:
 
1951
                return self.path
 
1952
            # quit
 
1953
            elif ch in [ord('q'), ord('Q'), curses.KEY_F10, 0x03]:  # Ctrl-C
 
1954
                return -1
 
1955
 
 
1956
            # else
 
1957
            else:
 
1958
                continue
 
1959
            
 
1960
            # update
 
1961
            self.regenerate_tree(newpos)