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.
- data/COPYING.txt +674 -0
- data/LICENSE.rdoc +20 -0
- data/README.rdoc +3 -0
- data/bin/keepyourhead +6 -0
- data/data/glade/DialogEditLatex.glade +180 -0
- data/data/glade/DialogEditText.glade +66 -0
- data/data/glade/DialogTrainStart.glade +101 -0
- data/data/glade/WindowEdit.glade +1419 -0
- data/data/glade/WindowTrain.glade +271 -0
- data/data/images/error_back.png +0 -0
- data/data/images/error_front.png +0 -0
- data/data/images/loading_back.png +0 -0
- data/data/images/loading_front.png +0 -0
- data/lib/Keepyourhead.rb +62 -0
- data/lib/Keepyourhead/Application.rb +94 -0
- data/lib/Keepyourhead/Cache.rb +233 -0
- data/lib/Keepyourhead/Compilation.rb +38 -0
- data/lib/Keepyourhead/Images.rb +62 -0
- data/lib/Keepyourhead/Preferences.rb +52 -0
- data/lib/Keepyourhead/Requirements.rb +72 -0
- data/lib/Keepyourhead/Resources.rb +45 -0
- data/lib/Keepyourhead/Training.rb +132 -0
- data/lib/Keepyourhead/Utils.rb +97 -0
- data/lib/Keepyourhead/Version.rb +43 -0
- data/lib/Keepyourhead/database/Base.rb +77 -0
- data/lib/Keepyourhead/database/BaseStatistic.rb +63 -0
- data/lib/Keepyourhead/database/BaseTopicFlashcardContainer.rb +43 -0
- data/lib/Keepyourhead/database/Collection.rb +43 -0
- data/lib/Keepyourhead/database/Database.rb +139 -0
- data/lib/Keepyourhead/database/File.rb +224 -0
- data/lib/Keepyourhead/database/FileRoot.rb +44 -0
- data/lib/Keepyourhead/database/Flashcard.rb +116 -0
- data/lib/Keepyourhead/database/Topic.rb +40 -0
- data/lib/Keepyourhead/database/Visitor.rb +33 -0
- data/lib/Keepyourhead/database/XmlAccessor.rb +315 -0
- data/lib/Keepyourhead/gui/Action.rb +91 -0
- data/lib/Keepyourhead/gui/DialogEditLatex.rb +132 -0
- data/lib/Keepyourhead/gui/DialogEditText.rb +104 -0
- data/lib/Keepyourhead/gui/DialogTrainStart.rb +63 -0
- data/lib/Keepyourhead/gui/FlashcardViewController.rb +112 -0
- data/lib/Keepyourhead/gui/WindowEdit.rb +469 -0
- data/lib/Keepyourhead/gui/WindowEditActions.rb +440 -0
- data/lib/Keepyourhead/gui/WindowEditAdapters.rb +329 -0
- data/lib/Keepyourhead/gui/WindowTrain.rb +167 -0
- data/lib/Keepyourhead/style/Style.rb +48 -0
- data/lib/Keepyourhead/style/StyleLatex.rb +235 -0
- 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
|