keepyourhead 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. data/COPYING.txt +674 -0
  2. data/LICENSE.rdoc +20 -0
  3. data/README.rdoc +3 -0
  4. data/bin/keepyourhead +6 -0
  5. data/data/glade/DialogEditLatex.glade +180 -0
  6. data/data/glade/DialogEditText.glade +66 -0
  7. data/data/glade/DialogTrainStart.glade +101 -0
  8. data/data/glade/WindowEdit.glade +1419 -0
  9. data/data/glade/WindowTrain.glade +271 -0
  10. data/data/images/error_back.png +0 -0
  11. data/data/images/error_front.png +0 -0
  12. data/data/images/loading_back.png +0 -0
  13. data/data/images/loading_front.png +0 -0
  14. data/lib/Keepyourhead.rb +62 -0
  15. data/lib/Keepyourhead/Application.rb +94 -0
  16. data/lib/Keepyourhead/Cache.rb +233 -0
  17. data/lib/Keepyourhead/Compilation.rb +38 -0
  18. data/lib/Keepyourhead/Images.rb +62 -0
  19. data/lib/Keepyourhead/Preferences.rb +52 -0
  20. data/lib/Keepyourhead/Requirements.rb +72 -0
  21. data/lib/Keepyourhead/Resources.rb +45 -0
  22. data/lib/Keepyourhead/Training.rb +132 -0
  23. data/lib/Keepyourhead/Utils.rb +97 -0
  24. data/lib/Keepyourhead/Version.rb +43 -0
  25. data/lib/Keepyourhead/database/Base.rb +77 -0
  26. data/lib/Keepyourhead/database/BaseStatistic.rb +63 -0
  27. data/lib/Keepyourhead/database/BaseTopicFlashcardContainer.rb +43 -0
  28. data/lib/Keepyourhead/database/Collection.rb +43 -0
  29. data/lib/Keepyourhead/database/Database.rb +139 -0
  30. data/lib/Keepyourhead/database/File.rb +224 -0
  31. data/lib/Keepyourhead/database/FileRoot.rb +44 -0
  32. data/lib/Keepyourhead/database/Flashcard.rb +116 -0
  33. data/lib/Keepyourhead/database/Topic.rb +40 -0
  34. data/lib/Keepyourhead/database/Visitor.rb +33 -0
  35. data/lib/Keepyourhead/database/XmlAccessor.rb +315 -0
  36. data/lib/Keepyourhead/gui/Action.rb +91 -0
  37. data/lib/Keepyourhead/gui/DialogEditLatex.rb +132 -0
  38. data/lib/Keepyourhead/gui/DialogEditText.rb +104 -0
  39. data/lib/Keepyourhead/gui/DialogTrainStart.rb +63 -0
  40. data/lib/Keepyourhead/gui/FlashcardViewController.rb +112 -0
  41. data/lib/Keepyourhead/gui/WindowEdit.rb +469 -0
  42. data/lib/Keepyourhead/gui/WindowEditActions.rb +440 -0
  43. data/lib/Keepyourhead/gui/WindowEditAdapters.rb +329 -0
  44. data/lib/Keepyourhead/gui/WindowTrain.rb +167 -0
  45. data/lib/Keepyourhead/style/Style.rb +48 -0
  46. data/lib/Keepyourhead/style/StyleLatex.rb +235 -0
  47. metadata +100 -0
@@ -0,0 +1,43 @@
1
+ module KeepYourHead
2
+
3
+ module Project
4
+ Major = 0
5
+ Minor = 2
6
+ Subminor = 0
7
+
8
+ FileMajor = 0
9
+ FileMinor = 1
10
+
11
+ VERSION = [Major,Minor, Subminor].join(".")
12
+ FILE_VERSION=[FileMajor, FileMinor].join(".")
13
+
14
+ GEM = "keepyourhead"
15
+ NAME = "KeepYourHead"
16
+ AUTHOR = "Oliver Burghard"
17
+ EMAIL = "OliverBurghard@web.de"
18
+ AUTHOR_WITH_EMAIL = "#{AUTHOR} (#{EMAIL})"
19
+ HOMEPAGE = "http://keepyourhead.rubyforge.org"
20
+ SUMMARY = "KeepYourHead is a latex based flashcard trainer under GPL3"
21
+ DESCRIPTION =<<END
22
+ #{SUMMARY}. It includes an editor as well as an trainer. Flashcards are build in latex. Latex is a powerful tool for \
23
+ descriping documents. The Flashcards are checked by letting the user judge if he knew the answer well enough.
24
+ END
25
+
26
+ COPYRIGHT = "Copyright 2008 Oliver Burghard"
27
+
28
+ LICENSE = ::File.open( Resources::system("../COPYING.txt"), "r" ) { |file| file.readlines.join("") }
29
+
30
+
31
+ BANNER = <<END
32
+ #{NAME}
33
+ #{COPYRIGHT}
34
+ Released under the GPL
35
+ END
36
+
37
+ end
38
+
39
+ end
40
+
41
+ module Project
42
+ include KeepYourHead::Project
43
+ end
@@ -0,0 +1,77 @@
1
+ # Copyright 2008 Burghard Oliver
2
+ #
3
+ # This file is part of KeepYourHead.
4
+ #
5
+ # KeepYourHead is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # KeepYourHead is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with KeepYourHead. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+
19
+ module KeepYourHead
20
+ module Database
21
+ class BaseItem
22
+ # def parent
23
+ # objectFromNode @node.parent
24
+ # end
25
+
26
+ def parent
27
+ throw ExceptionNotImplemented.new
28
+ #overwrite
29
+ end
30
+
31
+ def remove
32
+ parent.itemRemove self
33
+ end
34
+
35
+ def previous
36
+ parent.itemPrevious self
37
+ end
38
+ def next
39
+ parent.itemNext self
40
+ end
41
+ def children
42
+ []
43
+ end
44
+ end
45
+
46
+ class BaseItemWithXml < BaseItem
47
+ def self.my_define_method(*args, &proc)
48
+ define_method(*args, &proc)
49
+ end
50
+
51
+ include XmlAccessor
52
+
53
+ attr_reader :file, :node
54
+
55
+ def initialize( file, node)
56
+ @file = file
57
+ @node = node
58
+
59
+ assert @node
60
+ assert @file
61
+ end
62
+
63
+ def objectFromNode(node, &proc)
64
+ file.objectFromNode(node, &proc)
65
+ end
66
+
67
+ def parent
68
+ objectFromNode @node.parent
69
+ end
70
+
71
+ def database
72
+ file.database
73
+ end
74
+ end
75
+ end
76
+
77
+ end
@@ -0,0 +1,63 @@
1
+ # Copyright 2008 Burghard Oliver
2
+ #
3
+ # This file is part of KeepYourHead.
4
+ #
5
+ # KeepYourHead is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # KeepYourHead is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with KeepYourHead. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+
19
+ module KeepYourHead
20
+ module BaseStatistic
21
+ def collectFlashcards
22
+ items.map{ |item|
23
+ item.collectFlashcards
24
+ }.flatten
25
+ end
26
+
27
+
28
+
29
+ def count
30
+ items.map{ |item| item.count }.inject(0) { |a,b| a+b }
31
+ end
32
+ def countActive
33
+ items.map{ |item| item.countActive }.inject(0) { |a,b| a+b }
34
+ end
35
+ def countPassive
36
+ items.map{ |item| item.countPassive }.inject(0) { |a,b| a+b }
37
+ end
38
+
39
+ def distribution
40
+ all = items.map{ |item| item.distribution }
41
+
42
+ distribution = []
43
+
44
+ while all.inject(false) { |ret,set| ret ||= (set.length > 0) }
45
+ sum = 0
46
+ all.each { |set|
47
+ sum += set.pop || 0
48
+ }
49
+ distribution << sum
50
+ end
51
+
52
+ distribution = distribution.reverse
53
+
54
+ distribution
55
+ end
56
+
57
+ def removeStatistics
58
+ items.each{ |item| item.removeStatistics }
59
+ end
60
+ end
61
+
62
+
63
+ end
@@ -0,0 +1,43 @@
1
+ # Copyright 2008 Burghard Oliver
2
+ #
3
+ # This file is part of KeepYourHead.
4
+ #
5
+ # KeepYourHead is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # KeepYourHead is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with KeepYourHead. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+
19
+ module KeepYourHead
20
+ module Database
21
+ class BaseTopicFlashcardContainer < BaseItemWithXml
22
+
23
+ include BaseStatistic
24
+
25
+ xml = XmlAccessorElementList.new self, :item, /^topic|flashcard$/,
26
+ proc { |item,node|
27
+ item.objectFromNode(node) {
28
+ case node.name
29
+ when "topic"
30
+ Topic.new item.file, node
31
+ when "flashcard"
32
+ Flashcard.new item.file, node
33
+ end
34
+ }
35
+ }
36
+
37
+ xml.addRead
38
+ xml.addInsert :onItemInsert
39
+ xml.addRemove :onItemRemove
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,43 @@
1
+ # Copyright 2008 Burghard Oliver
2
+ #
3
+ # This file is part of KeepYourHead.
4
+ #
5
+ # KeepYourHead is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # KeepYourHead is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with KeepYourHead. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+
19
+ module KeepYourHead
20
+ module Database
21
+ class Collection < BaseTopicFlashcardContainer
22
+ def initialize( file, node )
23
+ super file, node
24
+ end
25
+
26
+ XmlAccessor::addElementText self, :name, "name", :onItemChange, proc { |item, v| v || "" }
27
+
28
+ XmlAccessor::addElementText self, :originAuthor, "OriginAuthor", :onItemChange, proc { |item, v| v || "" }
29
+ XmlAccessor::addElementText self, :originType, "OriginType", :onItemChange, proc { |item, v| v || "" }
30
+ XmlAccessor::addElementText self, :originDate, "OriginDate", :onItemChange, proc { |item, v| v || "" }
31
+
32
+ XmlAccessor::addElementCData self, :latexHeader, "LatexHeader", :onItemChange, proc { |item, v| v || "" }
33
+ XmlAccessor::addElementCData self, :latexAppend, "LatexAppend", :onItemChange, proc { |item, v| v || "" }
34
+ XmlAccessor::addElementCData self, :latexPrepend, "LatexPrepend", :onItemChange, proc { |item, v| v || "" }
35
+
36
+ def self.createNode( file )
37
+ obj = Collection.new file, REXML::Element.new( "collection" )
38
+ obj.name = "neue Collection"
39
+ obj.node
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,139 @@
1
+ # Copyright 2008 Burghard Oliver
2
+ #
3
+ # This file is part of KeepYourHead.
4
+ #
5
+ # KeepYourHead is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # KeepYourHead is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with KeepYourHead. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+
19
+ module KeepYourHead
20
+ module Database
21
+ class Database
22
+ def items
23
+ files
24
+ end
25
+ include BaseStatistic
26
+
27
+ def initialize
28
+ @viewers = []
29
+ @files = []
30
+
31
+ load
32
+ end
33
+
34
+ def files
35
+ @files
36
+ end
37
+
38
+ def load
39
+ ($preferences[:files] || []).each { |filename|
40
+ fileOpen filename if ::File.exist?( filename)
41
+ }
42
+ end
43
+ def writeBack
44
+ $preferences[:files] = files.map{ |file| file.filename }.compact
45
+ end
46
+
47
+ def saveAllChanged
48
+ files.each { |file|
49
+ file.save if file.changed
50
+ }
51
+ end
52
+
53
+ def fileOpen(filename)
54
+ filename = ::File.expand_path filename
55
+
56
+
57
+ if not files.map{ |file| file.filename }.include? filename then
58
+ file = KeepYourHead::Database::File.open( self, filename )
59
+
60
+ @files << file
61
+ file.viewerAdd self
62
+ viewersSend :onItemInsert, file
63
+ end
64
+ end
65
+ def fileNew
66
+ file = Database::File.createNew self
67
+ @files << file
68
+ file.viewerAdd self
69
+ viewersSend :onItemInsert, file
70
+ end
71
+ def fileClose(file)
72
+ file.viewerRemove self
73
+ @files.delete file
74
+ viewersSend :onItemRemove, file
75
+ end
76
+
77
+
78
+ # helper for moving files up and down
79
+ def moveUp( file )
80
+ assert file.kind_of?(Database::File)
81
+
82
+ viewersSend :onItemRemove, file
83
+ index = files.index file
84
+ assert index
85
+ files.delete_at(index)
86
+ files.insert([index-1,0].max,file)
87
+ viewersSend :onItemInsert, file
88
+ end
89
+ def moveDown( file )
90
+ assert file.kind_of?(Database::File)
91
+
92
+ viewersSend :onItemRemove, file
93
+ index = files.index file
94
+ assert index
95
+ files.delete_at(index)
96
+ files.insert([index+1,files.length].min,file)
97
+ viewersSend :onItemInsert, file
98
+ end
99
+
100
+
101
+ def viewerAdd( v )
102
+ @viewers << v unless @viewers.include? v
103
+ end
104
+
105
+ def viewerRemove( v )
106
+ @viewers.delete v
107
+ end
108
+
109
+ def viewersSend( name, *args )
110
+ assert name
111
+
112
+ @viewers.each{ |v|
113
+ v.send name, *args
114
+ }
115
+ end
116
+
117
+
118
+
119
+
120
+
121
+ def onItemChange(item)
122
+ viewersSend :onItemChange, item
123
+ end
124
+ def onItemRemove(item)
125
+ viewersSend :onItemRemove, item
126
+ end
127
+ def onItemInsert(item)
128
+ viewersSend :onItemInsert, item
129
+ end
130
+ def onReload(file)
131
+ viewersSend :onReload, file
132
+ end
133
+
134
+
135
+ end
136
+ end
137
+
138
+ end
139
+
@@ -0,0 +1,224 @@
1
+ # Copyright 2008 Burghard Oliver
2
+ #
3
+ # This file is part of KeepYourHead.
4
+ #
5
+ # KeepYourHead is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # KeepYourHead is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with KeepYourHead. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+
19
+ module KeepYourHead
20
+ module Database
21
+ class File
22
+ def items
23
+ root.collections
24
+ end
25
+ include BaseStatistic
26
+
27
+ attr_reader :filename
28
+ attr_reader :changed
29
+ attr_reader :root
30
+ attr_reader :database
31
+
32
+ # should not be called direct
33
+ def initialize(database)
34
+ @dom = nil
35
+ @styles = {}
36
+
37
+
38
+ @database = database
39
+
40
+ @viewers = []
41
+ viewerAdd(self)
42
+ end
43
+
44
+
45
+ def file
46
+ self
47
+ end
48
+
49
+
50
+
51
+ def viewerAdd( v )
52
+ @viewers << v unless @viewers.include? v
53
+ end
54
+
55
+ def viewerRemove( v )
56
+ @viewers.delete v
57
+ end
58
+
59
+ def viewersSend( name, *args )
60
+ assert name
61
+
62
+ @viewers.each{ |v|
63
+ v.send name, *args
64
+ }
65
+ end
66
+
67
+
68
+
69
+
70
+ #is his own visitor
71
+ def onItemChange(item)
72
+ setChanged if item.file == self
73
+ end
74
+ def onItemRemove(item)
75
+ setChanged if item.file == self
76
+ end
77
+ def onItemInsert(item)
78
+ setChanged if item.file == self
79
+ end
80
+ def onReload(file)
81
+ @changed = false
82
+ end
83
+
84
+
85
+ # should not be called direct
86
+ def loadFile(filename)
87
+ assert @dom == nil
88
+
89
+ @filename = filename
90
+
91
+ ::File.open( @filename ) { |file|
92
+ @dom = REXML::Document.new file
93
+ }
94
+
95
+ reload
96
+ end
97
+
98
+ # should not be called direct
99
+ def loadContent(contents)
100
+ assert @dom == nil
101
+
102
+ @filename = nil
103
+ @dom = REXML::Document.new(contents)
104
+
105
+ reload
106
+ end
107
+
108
+
109
+ def self.open(database, filename)
110
+ ret = File.new database
111
+ ret.loadFile filename
112
+ ret
113
+ end
114
+
115
+ def self.createNew(database)
116
+ ret = self.new database
117
+ content = "<flashcard_database version=\"#{Application::FILE_VERSION}\" />"
118
+ ret.loadContent content
119
+ ret.setChanged
120
+ ret
121
+ end
122
+
123
+ def filename=(filename)
124
+ @filename = filename
125
+ viewersSend :onItemChange, self
126
+ end
127
+
128
+
129
+
130
+ def reload
131
+ @mapObjectFromNode = {}
132
+
133
+ node = REXML::XPath.first( @dom, "flashcard_database" )
134
+
135
+ throw Exception.new("file not a flashcard database") unless node
136
+
137
+ # @root = FileRoot.new self, node
138
+ @root = objectFromNode(node) { || FileRoot.new self, node }
139
+
140
+ viewersSend "onReload", self
141
+ end
142
+
143
+
144
+ def objectFromNode(node)
145
+ @mapObjectFromNode[node] ||= yield
146
+ @mapObjectFromNode[node]
147
+ end
148
+
149
+
150
+ def normalizeWhitespace( parent )
151
+ if parent.kind_of?( REXML::Parent ) and
152
+ parent.children.select { |c| c.kind_of?(REXML::Element) }.length > 0 then
153
+
154
+ remove = []
155
+ parent.each { |node|
156
+ remove << node if node.kind_of?(REXML::Text)
157
+ }
158
+ remove.each { |node| parent.delete node }
159
+
160
+
161
+ indent = -1 #because the root is also counted
162
+ i = parent.parent
163
+ while i and i.kind_of?(REXML::Element) do
164
+ indent += 1
165
+ i = i.parent
166
+ end
167
+
168
+ parent.children.each { |c| parent.insert_before c, REXML::Text.new( "\n" + " " * (indent+1), true ) }
169
+ parent.insert_after parent.children.last, REXML::Text.new( "\n" + " " * indent, true )
170
+ end
171
+
172
+ if parent.kind_of?( REXML::Parent ) then
173
+ parent.children.each { |node|
174
+ normalizeWhitespace node
175
+ }
176
+ end
177
+ end
178
+
179
+
180
+ def save
181
+ assert @filename
182
+
183
+ FileUtils::mv( @filename, @filename + "~" ) if ::File.exist?(@filename)
184
+ saveAs @filename
185
+ end
186
+
187
+ def saveAs(filename)
188
+ assert filename
189
+
190
+ self.filename = filename
191
+
192
+ normalizeWhitespace @dom.root
193
+
194
+ ::File.open( self.filename, "w" ) { |file|
195
+ @dom.write file
196
+ }
197
+ @changed = false
198
+ end
199
+
200
+ def setChanged
201
+ @changed = true
202
+ end
203
+
204
+
205
+
206
+
207
+
208
+ def style(name)
209
+ if not @styles[name] then
210
+ s = KeepYourHead::Database::Style.getStyle(name)
211
+ assert s
212
+ @styles[name] = s.new(self)
213
+ end
214
+
215
+ assert @styles[name]
216
+ @styles[name]
217
+ end
218
+ end
219
+
220
+
221
+ end
222
+
223
+
224
+ end