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,44 @@
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 FileRoot < BaseItemWithXml
22
+ def initialize( file, node )
23
+ super file, node
24
+
25
+ assert self.version == Project::FILE_VERSION
26
+
27
+ end
28
+
29
+ XmlAccessor.addAttribute self, :version, "version", :onItemChange, proc { |item,v| v }
30
+
31
+ xml = XmlAccessorElementList.new self, :collection, /^collection$/,
32
+ proc { |item,node|
33
+ item.objectFromNode(node) {
34
+ Collection.new item.file, node
35
+ }
36
+ }
37
+
38
+ xml.addRead
39
+ xml.addInsert :onItemInsert
40
+ xml.addRemove :onItemRemove
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,116 @@
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 Flashcard < BaseItemWithXml
22
+ XmlAccessor::addElementCData self, :front, "front", :onItemChange, proc { |item,v| v || "" }
23
+ XmlAccessor::addElementCData self, :back, "back", :onItemChange, proc { |item,v| v || "" }
24
+
25
+ XmlAccessor::addAttribute self, :name, "name", :onItemChange, proc { |item,v| v || "" }
26
+ XmlAccessor::addAttribute self, :type, "type", :onItemChange, proc { |item,v| v || "" }
27
+ XmlAccessor::addAttribute self, :style, "style", :onItemChange, proc { |item,v| v || "" }
28
+
29
+ XmlAccessor::addElementText self, :nextCheck, "nextCheck", :onItemChange, proc { |item, v| (v && Time.parse(v)) || (Time.now - 60) }
30
+ XmlAccessor::addElementText self, :level, "level", :onItemChange, proc { |item, v| (v && v.to_i) || 0 }
31
+
32
+ # XmlAccessor::addElementText self, :cacheFilename, "cacheFilename", nil
33
+ # XmlAccessor::addElementText self, :cacheFrontContentHash, "cacheFrontContentHash", nil
34
+ # XmlAccessor::addElementText self, :cacheFrontFileHash, "cacheFrontFileHash", nil
35
+ # XmlAccessor::addElementText self, :cacheBackContentHash, "cacheBackContentHash", nil
36
+
37
+
38
+ # some functions defined on all database entities for iteration
39
+ def collectFlashcards
40
+ [self]
41
+ end
42
+
43
+ def count
44
+ 1
45
+ end
46
+ def countActive
47
+ active? ? 1 : 0
48
+ end
49
+ def countPassive
50
+ active? ? 0 : 1
51
+ end
52
+
53
+ def distribution
54
+ distribution = []
55
+
56
+ distribution[self.level] = 1
57
+
58
+ distribution
59
+ end
60
+
61
+ def removeStatistics
62
+ self.level = 0
63
+ self.nextCheck = Time.new - 60
64
+ end
65
+
66
+
67
+
68
+
69
+ def active?
70
+ nextCheck <= Time.now
71
+ end
72
+
73
+ def content(type, options = {})
74
+ styleInstance = file.style(self.style)
75
+ styleInstance.content(type, self, options)
76
+ end
77
+ def compileImage(type, options = {})
78
+ styleInstance = file.style(self.style)
79
+ compilation = styleInstance.createImage(type, self, options )
80
+ end
81
+
82
+ def collection
83
+ ret = self
84
+ while ret and not ret.kind_of? Collection
85
+ ret = ret.parent
86
+ end
87
+ ret
88
+ end
89
+
90
+ def topic
91
+ parent && parent.class == Topic && parent
92
+ end
93
+ def topicNames
94
+ topics = []
95
+
96
+ n = topic
97
+ while n do
98
+ topics << n.name
99
+ n = n.topic
100
+ end
101
+
102
+ topics = topics.reverse
103
+ topics
104
+ end
105
+
106
+
107
+ def self.createNode( file )
108
+ obj = Flashcard.new file, ::REXML::Element.new("flashcard")
109
+ obj.name = "neue Flashcard"
110
+ obj.style = "latex"
111
+ obj.node
112
+ end
113
+ end
114
+ end
115
+
116
+ end
@@ -0,0 +1,40 @@
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 Topic < BaseTopicFlashcardContainer
22
+ def initialize( file, node )
23
+ super file, node
24
+ end
25
+
26
+ XmlAccessor::addAttribute self, :name, "name", :onItemChange
27
+
28
+ def topic
29
+ parent && parent.class == Topic && parent
30
+ end
31
+
32
+ def self.createNode(file)
33
+ obj = Topic.new file, ::REXML::Element.new("topic")
34
+ obj.name = "neues Topic"
35
+ obj.node
36
+ end
37
+ end
38
+ end
39
+ end
40
+
@@ -0,0 +1,33 @@
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 Visitor
22
+ def onItemChange(item)
23
+ end
24
+ def onItemRemove(item)
25
+ end
26
+ def onItemInsert(item)
27
+ end
28
+ def onReload()
29
+ end
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,315 @@
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 XmlAccessor
21
+ def xmlAccessorElementCDataRead( name, procRead )
22
+ parent = REXML::XPath.first( node, name )
23
+ ret = parent && parent.children.map{ |c|
24
+ case c
25
+ when REXML::Text
26
+ c.value
27
+ when REXML::CData
28
+ c.value
29
+ else
30
+ nil
31
+ end
32
+ }.compact.join("")
33
+ (procRead && procRead.call(self, ret) ) || ret
34
+ end
35
+
36
+ def xmlAccessorElementCDataWrite( name, notifyEvent, value, procWrite )
37
+ lastValue = (val = REXML::XPath.first( node, name )) && val.cdatas.map{ |cd| cd.value }.join("")
38
+
39
+
40
+ newValue = (procWrite && procWrite.call(self, value)) || value
41
+
42
+ node_ = REXML::XPath.first( node, name )
43
+ node_ ||= @node.add REXML::Element.new(name)
44
+
45
+ if lastValue != newValue then
46
+ node_.delete_at 0 while node_.length > 0
47
+
48
+ node_.add REXML::CData.new(newValue)
49
+
50
+ file.viewersSend notifyEvent, self if notifyEvent
51
+ end
52
+ end
53
+
54
+ def self.addElementCData( _class, functionName, elementName, notifyEvent, procRead = nil, procWrite = nil )
55
+ _class.my_define_method(functionName.to_sym) {
56
+ xmlAccessorElementCDataRead elementName, procRead
57
+ }
58
+ _class.my_define_method( (functionName.to_s + "=").to_sym ) { |value|
59
+ xmlAccessorElementCDataWrite elementName, notifyEvent, value, procWrite
60
+ }
61
+ end
62
+
63
+
64
+
65
+
66
+
67
+
68
+ def xmlAccessorAttributeRead( name, procRead )
69
+ ret = @node.attributes[name]
70
+ (procRead && procRead.call(self, ret) ) || ret
71
+ end
72
+
73
+ def xmlAccessorAttributeWrite( name, notifyEvent, value, procWrite )
74
+ value = (procWrite && procWrite.call(self, value)) || value
75
+
76
+ if @node.attributes[name] != value then
77
+ @node.attributes[name] = value
78
+
79
+ file.viewersSend notifyEvent, self if notifyEvent
80
+ end
81
+ end
82
+
83
+ def self.addAttribute( _class, functionName, elementName, notifyEvent, procRead = nil, procWrite = nil )
84
+ _class.my_define_method(functionName.to_sym) {
85
+ xmlAccessorAttributeRead elementName, procRead
86
+ }
87
+ _class.my_define_method( (functionName.to_s + "=").to_sym ) { |value|
88
+ xmlAccessorAttributeWrite elementName, notifyEvent, value, procWrite
89
+ }
90
+ end
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+ def xmlAccessorElementTextRead( name, procRead )
99
+ n = REXML::XPath.first( node, name )
100
+ ret = n && n.text
101
+
102
+ (procRead && procRead.call(self,ret) ) || ret
103
+ end
104
+
105
+ def xmlAccessorElementTextWrite( name, notifyEvent, value, procWrite )
106
+ value = (procWrite && procWrite.call(self,value)) || value
107
+
108
+ n = REXML::XPath.first( node, name )
109
+
110
+ if not n or n.text != value then
111
+ n ||= node.add REXML::Element.new(name)
112
+ n.text=value
113
+
114
+ file.viewersSend notifyEvent, self if notifyEvent
115
+ end
116
+ end
117
+
118
+ def self.addElementText( _class, functionName, elementName, notifyEvent, procRead = nil, procWrite = nil )
119
+ _class.my_define_method(functionName.to_sym) {
120
+ xmlAccessorElementTextRead elementName, procRead
121
+ }
122
+ _class.my_define_method( (functionName.to_s + "=").to_sym ) { |value|
123
+ xmlAccessorElementTextWrite elementName, notifyEvent, value, procWrite
124
+ }
125
+ end
126
+
127
+
128
+
129
+
130
+
131
+
132
+
133
+ def xmlAccessorElementListRead( name, procRead )
134
+ ret = @node.elements.select { |node| node.name =~ name }
135
+ ret.map! { |node|
136
+ (procRead && procRead.call(self,node) ) || node.name
137
+ }
138
+ end
139
+
140
+ def xmlAccessorElementListNext( name, procRead, other )
141
+ assert other.parent == self
142
+
143
+ ret = other.node
144
+ begin
145
+ ret = ret.next_element
146
+ end while (ret and not ret.name =~ name)
147
+
148
+ return nil unless ret
149
+
150
+ (procRead && procRead.call(self,ret) ) || ret.name
151
+ end
152
+
153
+ def xmlAccessorElementListPrevious( name, procRead, other )
154
+ assert other.parent == self
155
+
156
+ ret = other.node
157
+ begin
158
+ ret = ret.previous_element
159
+ end while ret and not ret.name =~ name
160
+
161
+ return nil unless ret
162
+
163
+ (procRead && procRead.call(self,ret) ) || ret.name
164
+ end
165
+
166
+ def xmlAccessorElementListRemove( name, notifyEvent, item )
167
+ assert item.node.name =~ name
168
+ assert item.parent == self
169
+
170
+ file.viewersSend notifyEvent, item if notifyEvent
171
+
172
+ #node.delete_element item.node
173
+ item.node.remove
174
+
175
+ item.node
176
+ end
177
+
178
+ def xmlAccessorElementListInsertFirst( name, notifyEvent, procRead, node )
179
+ assert node.kind_of?(REXML::Element)
180
+ assert node.name =~ name
181
+
182
+ if self.node[0] then
183
+ self.node.insert_before self.node[0], node
184
+ else
185
+ self.node.add node
186
+ end
187
+
188
+ ret = (procRead && procRead.call(self,node) ) || node.name
189
+
190
+ file.viewersSend notifyEvent, ret if notifyEvent
191
+
192
+ ret
193
+ end
194
+
195
+ def xmlAccessorElementListInsertLast( name, notifyEvent, procRead, node )
196
+ assert node.kind_of?(REXML::Element)
197
+ assert node.name =~ name
198
+
199
+ self.node.add node
200
+
201
+ ret = (procRead && procRead.call(self,node) ) || node.name
202
+
203
+ file.viewersSend notifyEvent, ret if notifyEvent
204
+
205
+ ret
206
+ end
207
+
208
+ def xmlAccessorElementListInsertBefore( name, notifyEvent, procRead, node, other )
209
+ assert node.kind_of?(REXML::Element)
210
+ assert node.name =~ name
211
+ assert other
212
+
213
+ assert other.parent == self
214
+ other.node.parent.insert_before other.node, node
215
+ # other.node.previous_sibling = node
216
+
217
+ ret = (procRead && procRead.call(self,node) ) || node.name
218
+
219
+ file.viewersSend notifyEvent, ret if notifyEvent
220
+
221
+ ret
222
+ end
223
+
224
+ def xmlAccessorElementListInsertAfter( name, notifyEvent, procRead, node, other )
225
+ assert node.kind_of?(REXML::Element)
226
+ assert node.name =~ name
227
+ assert other
228
+
229
+ assert other.parent == self
230
+ other.node.parent.insert_after other.node, node
231
+ # other.node.next_sibling = node
232
+
233
+ ret = (procRead && procRead.call(self,node) ) || node.name
234
+
235
+ file.viewersSend notifyEvent, ret if notifyEvent
236
+
237
+ ret
238
+ end
239
+
240
+ def xmlAccessorElementListCreate( name, notifyEvent, procCreate )
241
+ =begin
242
+ node = REXML::Element.new name
243
+
244
+ if self.node[0] then
245
+ self.node.insert_before self.node[0], node
246
+ else
247
+ self.node.add node
248
+ end
249
+ =end
250
+ # node = self.node.add_element name
251
+ node = self.node.add REXML::Element.new(name)
252
+
253
+ ret = (procCreate && procCreate.call(self,node)) || node.name
254
+
255
+ file.viewersSend notifyEvent, ret if notifyEvent
256
+
257
+ ret
258
+ end
259
+
260
+ class XmlAccessorElementList
261
+ attr_reader :_class, :functionName, :elementRegExp, :procRead
262
+ def initialize(_class, functionName, elementRegExp, procRead )
263
+ @_class, @functionName, @elementRegExp, @procRead =
264
+ _class, functionName, elementRegExp, procRead
265
+ end
266
+ def _addRead(elementRegExp,procRead)
267
+ _class.my_define_method((functionName.to_s + "s").to_sym) {
268
+ xmlAccessorElementListRead elementRegExp, procRead
269
+ }
270
+ _class.my_define_method((functionName.to_s + "Next").to_sym) { |other|
271
+ xmlAccessorElementListNext elementRegExp, procRead, other
272
+ }
273
+ _class.my_define_method((functionName.to_s + "Previous").to_sym) { |other|
274
+ xmlAccessorElementListPrevious elementRegExp, procRead, other
275
+ }
276
+ end
277
+ def addRead
278
+ _addRead(elementRegExp, procRead)
279
+ end
280
+ def _addRemove(elementRegExp, notifyEvent)
281
+ _class.my_define_method((functionName.to_s + "Remove").to_sym) { |item|
282
+ xmlAccessorElementListRemove elementRegExp, notifyEvent, item
283
+ }
284
+ end
285
+ def addRemove(notifyEvent)
286
+ _addRemove(elementRegExp, notifyEvent)
287
+ end
288
+ def _addInsert(elementRegExp, procRead, notifyEvent)
289
+ _class.my_define_method((functionName.to_s + "InsertFirst").to_sym) { |node|
290
+ xmlAccessorElementListInsertFirst elementRegExp, notifyEvent, procRead, node
291
+ }
292
+ _class.my_define_method((functionName.to_s + "InsertLast").to_sym) { |node|
293
+ xmlAccessorElementListInsertLast elementRegExp, notifyEvent, procRead, node
294
+ }
295
+ _class.my_define_method((functionName.to_s + "InsertBefore").to_sym) { |node,other|
296
+ xmlAccessorElementListInsertBefore elementRegExp, notifyEvent, procRead, node, other
297
+ }
298
+ _class.my_define_method((functionName.to_s + "InsertAfter").to_sym) { |node,other|
299
+ xmlAccessorElementListInsertAfter elementRegExp, notifyEvent, procRead, node, other
300
+ }
301
+ end
302
+ def addInsert(notifyEvent)
303
+ _addInsert(elementRegExp, procRead, notifyEvent)
304
+ end
305
+ def addCreate(functionName, elementName, notifyEvent, procCreate)
306
+ _class.my_define_method((functionName.to_s + "Create").to_sym) { ||
307
+ xmlAccessorElementListCreate elementName, notifyEvent, procCreate
308
+ }
309
+ end
310
+ end
311
+ end
312
+
313
+
314
+ end
315
+