mireru 0.2.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7ebe6191f01182968abdb9fdfb6b3e9f409e7a34
4
- data.tar.gz: d64056047895dbf66885ce81b2fdb10ed1a7e905
3
+ metadata.gz: fdbbb02cb56552275b740544a7156e7b155bd126
4
+ data.tar.gz: efb1f67b291ec5733cf9499f6ca71cb4969251cd
5
5
  SHA512:
6
- metadata.gz: a03ed7b019779753b3eddb07bed3aecc9a4f30cbd96665838909ef1ed3c393d4d81fb91063ccbbcaa5d30c7c571620b5586c076deec62c2cb1fe655b98cc34d2
7
- data.tar.gz: 24dd3afe0d6f16091a384cc08db23eeae127daa84ec7b90a69df998bbb31570b9ef2552d00f65197ba74396174f9042c360ec8fb468ac3f453f56ce089523ac0
6
+ metadata.gz: d73f9d68826bb2dc43fa3a9719e1b1d053bfe119a33c194660c26dfbdb7223ebfd5a3b6a292239a6f30e4841066ec552313be858edc719d72e10dba6e09a970d
7
+ data.tar.gz: 55021cc099d4abef5652d11fef73e72cd170dd71c1b29291c90bfa7e1b0c9f0df4f406b3c174e9aa8f69089edb5e79734a0a216bed20523a2d479046622c02fa
data/NEWS.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # NEWS
2
2
 
3
+ ## 0.9.0: 2014-07-13
4
+
5
+ Now we have TreeView, and many problems are resolved.
6
+
7
+ ### Changes
8
+
9
+ * Improvements
10
+ * Improve scrolling movements.
11
+ * Save CPU and memory for distinction between text and binary.
12
+ * Improve help messages.
13
+ * Remove thumbnail function.
14
+ * pdf: Support multiple pages.
15
+ * Fit a parent widget (PDF, SVG and Video).
16
+ * Support music files.
17
+ * Add key bindings.
18
+ * Introduce Navigator as Gtk::TreeView.
19
+
20
+ * Fixes
21
+ * image: Enable animation for image files such as animated GIF.
22
+ * video: Fix a bug that destroyed object is called.
23
+
3
24
  ## 0.2.1: 2014-05-29
4
25
 
5
26
  ### Changes
data/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # Mireru [![Build Status](https://secure.travis-ci.org/myokoym/mireru.png?branch=master)](http://travis-ci.org/myokoym/mireru)
2
2
 
3
- A file viewer with a focus on flexibility by Ruby/GTK3.
3
+ Mireru is a keyboard friendly file viewer by Ruby/GTK3.
4
4
 
5
- A friend of a keyboard.
5
+ It can handle a variety of file types (Picture, Text, PDF, Video and etc.).
6
6
 
7
7
  ## Requirements
8
8
 
9
- * Ruby/GTK3, Ruby/GtkSourceView3, Ruby/ClutterGTK, Ruby/ClutterGStreamer
10
- , Ruby/Poppler and Ruby/RSVG2 in
9
+ * Ruby/GTK3, Ruby/GtkSourceView3, Ruby/ClutterGTK, Ruby/ClutterGStreamer,
10
+ Ruby/Poppler and Ruby/RSVG2 in
11
11
  [Ruby-GNOME2](http://ruby-gnome2.sourceforge.jp/)
12
12
  * [hexdump](https://github.com/postmodern/hexdump)
13
13
 
@@ -19,28 +19,36 @@ A friend of a keyboard.
19
19
 
20
20
  ### Launch
21
21
 
22
- $ mireru [OPTION]... [FILE]...
22
+ $ mireru [OPTION]... [FILE_OR_DIRECTORY]...
23
23
 
24
- If no argument, then search current directory.
24
+ If no argument, then open the current directory.
25
25
 
26
26
  ### Options
27
27
 
28
- -R, --recursive<br />
29
- recursive search as "**/*"
28
+ -h, --help<br />
29
+ show this help message
30
30
 
31
31
  -f, --font NAME<br />
32
- set font such as "Monospace 16"
32
+ set a font such as "Monospace 16"
33
33
 
34
- ### Keybind
34
+ ### Key bindings
35
35
 
36
36
  #### Common
37
37
 
38
38
  n: next<br />
39
39
  p: prev<br />
40
+ e: expand/collpse<br />
40
41
  r: reload<br />
41
- e: expand path<br />
42
42
  q: quit<br />
43
43
 
44
+ #### Control key mask
45
+
46
+ Ctrl+n: 10 tiles next<br />
47
+ Ctrl+p: 10 tiles prev<br />
48
+ Ctrl+e: expand all/collpse even if cursor on file<br />
49
+ Ctrl+h: move position of partition to left<br />
50
+ Ctrl+l: move position of partition to right<br />
51
+
44
52
  #### Scroll
45
53
 
46
54
  h: left<br />
@@ -48,19 +56,22 @@ j: down<br />
48
56
  k: up<br />
49
57
  l: right<br />
50
58
 
59
+ Shift+h: 100 times left<br />
60
+ Shift+j: 100 times down<br />
61
+ Shift+k: 100 times up<br />
62
+ Shift+l: 100 times right<br />
63
+
64
+ Shift+g: down to bottom<br />
65
+
51
66
  #### Scale
52
67
 
53
68
  +: larger<br />
54
69
  -: smaller<br />
55
70
 
56
- #### Special
57
-
58
- T: thumbnail
59
-
60
71
  #### Image
61
72
 
62
- f: fits window size<br />
63
- o: original size<br />
73
+ f: fit window size<br />
74
+ o: scale to the original size<br />
64
75
 
65
76
  #### Text
66
77
 
@@ -70,6 +81,11 @@ f: change font (at random)<br />
70
81
 
71
82
  space: play/pause<br />
72
83
 
84
+ #### PDF
85
+
86
+ j: next page<br />
87
+ k: prev page<br />
88
+
73
89
  ## License
74
90
 
75
91
  Copyright (c) 2013-2014 Masafumi Yokoyama <myokoym@gmail.com>
@@ -1,8 +1,8 @@
1
1
  require "mireru/version"
2
- require "mireru/container"
3
2
  require "mireru/logger"
4
3
  require "mireru/widget"
5
4
  require "mireru/window"
5
+ require "mireru/navigator"
6
6
 
7
7
  module Mireru
8
8
  end
@@ -1,13 +1,11 @@
1
- require "gtk3"
2
1
  require "mireru/logger"
3
2
  require "mireru/window"
4
- require "mireru/container"
5
3
  require "mireru/version"
6
4
 
7
5
  module Mireru
8
6
  module Command
9
7
  class Mireru
10
- USAGE = "Usage: mireru [OPTION]... [FILE]..."
8
+ USAGE = "Usage: mireru [OPTION]... [FILE_OR_DIRECTORY]..."
11
9
 
12
10
  class << self
13
11
  def run(*arguments)
@@ -31,44 +29,17 @@ module Mireru
31
29
  font = purge_option(arguments, /\A(-f|--font)\z/, true)
32
30
 
33
31
  files = files_from_arguments(arguments)
34
- file_container = ::Mireru::Container.new(files)
35
32
 
36
- if file_container.empty?
37
- write_empty_message
38
- exit(false)
39
- end
40
-
41
- window = ::Mireru::Window.new
33
+ window = ::Mireru::Window.new(files)
42
34
  window.font = font if font
43
- window.add_container(file_container)
44
35
 
45
- Gtk.main
36
+ window.run
46
37
  end
47
38
 
48
39
  private
49
40
  def files_from_arguments(arguments)
50
41
  if arguments.empty?
51
- files = Dir.glob("*")
52
- elsif purge_option(arguments, /\A(-R|--recursive|-d|--deep)\z/)
53
- if arguments.empty?
54
- files = Dir.glob("**/*")
55
- else
56
- files = []
57
- arguments.each do |f|
58
- if File.directory?(f)
59
- files << Dir.glob("#{f}/**/*")
60
- else
61
- files << f
62
- end
63
- end
64
- files.flatten!
65
- end
66
- elsif arguments.all? {|v| File.directory?(v) }
67
- files = []
68
- arguments.each do |f|
69
- files << Dir.glob("#{f}/*")
70
- end
71
- files.flatten!
42
+ files = [Dir.pwd]
72
43
  else
73
44
  files = arguments
74
45
  end
@@ -89,38 +60,59 @@ module Mireru
89
60
  def write_help_message
90
61
  message = <<-EOM
91
62
  #{USAGE}
92
- If no argument, then search current directory.
63
+ If no argument, then open the current directory.
64
+
93
65
  Options:
94
- -R, --recursive
95
- recursive search as "**/*"
66
+ -h, --help
67
+ show this help message
68
+
96
69
  -f, --font NAME
97
- set font such as "Monospace 16"
98
- Keybind:
70
+ set a font such as "Monospace 16"
71
+
72
+ Key bindings:
99
73
  n: next
100
74
  p: prev
75
+ e: expand/collpse
101
76
  r: reload
102
- e: expand path
103
77
  q: quit
104
78
 
79
+ Control key mask:
80
+ Ctrl+n: 10 tiles next
81
+ Ctrl+p: 10 tiles prev
82
+ Ctrl+e: expand all / collpse even if cursor on file
83
+ Ctrl+h: move position of partition to left
84
+ Ctrl+l: move position of partition to right
85
+
105
86
  scroll:
106
87
  h: left
107
88
  j: down
108
89
  k: up
109
90
  l: right
110
91
 
92
+ Shift+h: 100 times left
93
+ Shift+j: 100 times down
94
+ Shift+k: 100 times up
95
+ Shift+l: 100 times right
96
+
97
+ Shift+g: down to bottom
98
+
111
99
  scale:
112
100
  +: larger
113
101
  -: smaller
114
102
 
115
103
  image:
116
- f: fits window size
117
- o: original size
104
+ f: fit window size
105
+ o: scale to the original size
118
106
 
119
107
  text:
120
108
  f: change font (at random)
121
109
 
122
110
  video:
123
111
  space: play/pause
112
+
113
+ PDF:
114
+ j: next page
115
+ k: prev page
124
116
  EOM
125
117
  @logger.info(message)
126
118
  end
@@ -131,20 +123,6 @@ Keybind:
131
123
  EOM
132
124
  @logger.info(message)
133
125
  end
134
-
135
- def write_empty_message
136
- message = <<-EOM
137
- Warning: file not found.
138
- #{USAGE}
139
- If no argument, then search current directory.
140
- Options:
141
- -R, --recursive
142
- recursive search as "**/*"
143
- -f, --font NAME
144
- set font such as "Monospace 16"
145
- EOM
146
- @logger.error(message)
147
- end
148
126
  end
149
127
  end
150
128
  end
@@ -0,0 +1,166 @@
1
+ require "gtk3"
2
+
3
+ module Mireru
4
+ class Navigator < Gtk::ScrolledWindow
5
+ PATH_COLUMN, FILENAME_COLUMN, ICON_COLUMN = 0, 1, 2
6
+
7
+ def initialize(window, files)
8
+ super()
9
+ @window = window
10
+ @files = files
11
+ @dir_iters = {}
12
+ set_policy(:automatic, :automatic)
13
+ set_size_request(200, -1)
14
+ @model = Gtk::TreeStore.new(String, String, Gdk::Pixbuf)
15
+ @tree_view = create_tree(@model)
16
+ add(@tree_view)
17
+ end
18
+
19
+ def next
20
+ @tree_view.move_cursor(Gtk::MovementStep::DISPLAY_LINES, 1)
21
+ end
22
+
23
+ def prev
24
+ @tree_view.move_cursor(Gtk::MovementStep::DISPLAY_LINES, -1)
25
+ end
26
+
27
+ def expand_toggle(open_all=false)
28
+ path = selected_path
29
+ iter = @model.get_iter(path)
30
+ file_path = iter.get_value(PATH_COLUMN)
31
+ if open_all and File.file?(file_path)
32
+ parent = iter.parent
33
+ path = @model.get_path(parent)
34
+ @tree_view.collapse_row(path)
35
+ elsif @tree_view.row_expanded?(path)
36
+ @tree_view.collapse_row(path)
37
+ else
38
+ if open_all
39
+ return unless File.directory?(file_path)
40
+ Dir.glob("#{file_path}/*") do |dir|
41
+ next unless File.directory?(dir)
42
+ child_iter = @dir_iters[dir]
43
+ next unless child_iter
44
+ load_dir(@model, dir, child_iter, true)
45
+ @dir_iters.delete(dir)
46
+ end
47
+ end
48
+ @tree_view.expand_row(path, open_all)
49
+ end
50
+ end
51
+
52
+ def selected_path
53
+ selection = @tree_view.selection
54
+ selected = selection.selected
55
+ @model.get_path(selected)
56
+ end
57
+
58
+ private
59
+ def create_tree(model)
60
+ tree_view = Gtk::TreeView.new
61
+ tree_view.set_model(model)
62
+ tree_view.search_column = FILENAME_COLUMN
63
+ tree_view.enable_search = false
64
+
65
+ selection = tree_view.selection
66
+ selection.set_mode(:browse)
67
+
68
+ @files.each do |file|
69
+ load_file(model, file)
70
+ end
71
+
72
+ column = Gtk::TreeViewColumn.new
73
+ if @files.size == 1
74
+ column.title = File.dirname(@files.first)
75
+ else
76
+ column.title = "Selected Files"
77
+ end
78
+ tree_view.append_column(column)
79
+
80
+ renderer = Gtk::CellRendererPixbuf.new
81
+ renderer.set_fixed_size(*Gtk::IconSize.lookup(:menu))
82
+ column.pack_start(renderer, :expand => false)
83
+ column.add_attribute(renderer, :pixbuf, ICON_COLUMN)
84
+
85
+ renderer = Gtk::CellRendererText.new
86
+ column.pack_start(renderer, :expand => false)
87
+ column.add_attribute(renderer, :text, FILENAME_COLUMN)
88
+
89
+ selection.signal_connect("changed") do |selection|
90
+ apply_changed(selection)
91
+ end
92
+
93
+ tree_view.expand_all
94
+ tree_view
95
+ end
96
+
97
+ def apply_changed(selection)
98
+ iter = selection.selected
99
+ return unless iter
100
+ path = iter.get_value(PATH_COLUMN)
101
+ if File.directory?(path)
102
+ if @dir_iters[path]
103
+ load_dir(@model, path, @dir_iters[path])
104
+ end
105
+ @dir_iters.delete(path)
106
+ end
107
+ return unless File.file?(path)
108
+ @window.title = path
109
+ @window.file = path
110
+ begin
111
+ GLib::Timeout.add(100) do
112
+ if @window.file == path
113
+ begin
114
+ @window.add_from_file(path)
115
+ rescue => e
116
+ $stderr.puts("#{e.class}: #{e.message}")
117
+ $stderr.puts(e.backtrace)
118
+ end
119
+ end
120
+ false
121
+ end
122
+ rescue
123
+ stock = Gtk::Stock::MISSING_IMAGE
124
+ size = :dialog
125
+ pixbuf = Gtk::Image.new.render_icon_pixbuf(stock, size)
126
+ end
127
+ end
128
+
129
+ def load_dir(model, dir, parent=nil, recursive=false)
130
+ Dir.glob("#{File.expand_path(dir)}/*") do |child|
131
+ load_file(model, child, parent, recursive)
132
+ end
133
+ end
134
+
135
+ def load_file(model, file, parent=nil, recursive=false)
136
+ iter = model.append(parent)
137
+ iter.set_value(PATH_COLUMN, file)
138
+ iter.set_value(FILENAME_COLUMN, File.basename(file))
139
+ if File.directory?(file)
140
+ @dir_iters[file] = iter unless recursive
141
+ dir_icon = self.render_icon_pixbuf(Gtk::Stock::DIRECTORY, :menu)
142
+ iter.set_value(ICON_COLUMN, dir_icon)
143
+ load_dir(model, file, iter, recursive) if recursive
144
+ else
145
+ file_icon = select_icon(file)
146
+ iter.set_value(ICON_COLUMN, file_icon)
147
+ end
148
+ # TODO: too slow...
149
+ #icon_width, icon_height = Gtk::IconSize.lookup(:menu)
150
+ #begin
151
+ # pixbuf = Gdk::Pixbuf.new(file_path, icon_width, icon_height)
152
+ #rescue Gdk::PixbufError
153
+ # pixbuf = file_icon
154
+ #end
155
+ #iter.set_value(ICON_COLUMN, pixbuf)
156
+ end
157
+
158
+ def select_icon(file)
159
+ if Widget.video?(file) or Widget.music?(file)
160
+ self.render_icon_pixbuf(Gtk::Stock::CDROM, :menu)
161
+ else
162
+ self.render_icon_pixbuf(Gtk::Stock::FILE, :menu)
163
+ end
164
+ end
165
+ end
166
+ end