Scid  4.7.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
file.tcl
Go to the documentation of this file.
1 # ::file::Exit
2 #
3 # Prompt for confirmation then exit.
4 #
5 proc ::file::Exit {} {
6  # Check for altered game in all bases except the clipbase:
7  set unsavedCount 0
8  set savedBase [sc_base current]
9  set msg ""
10  foreach i [sc_base list] {
11  sc_base switch $i
12  if {[sc_game altered] && ![sc_base isReadOnly $i]} {
13  if {$unsavedCount == 0} {
14  append msg $::tr(ExitUnsaved)
15  append msg "\n\n"
16  }
17  incr unsavedCount
18  set fname [file tail [sc_base filename $i]]
19  set g [sc_game number]
20  append msg " Base $i: $fname "
21  append msg "($::tr(game) $g)"
22  append msg "\n"
23  }
24  }
25  # Switch back to original database:
26  sc_base switch $savedBase
27 
28  # Check if a mask is opened and dirty
30 
31  if {$msg != ""} {
32  append msg "\n"
33  }
34  append msg $::tr(ExitDialog)
35 
36  # Only ask before exiting if there are unsaved changes:
37  if {$unsavedCount > 0} {
38  set answer [tk_messageBox -title "Scid: [tr FileExit]" \
39  -message $msg -type yesno -icon question]
40  if {$answer != "yes"} { return}
41  }
42  if {$::optionsAutoSave} {
44  }
47  destroy .
48 }
49 
50 
51 # ::file::New
52 #
53 # Opens file-save dialog and creates a new database.
54 #
55 proc ::file::New {} {
56  set ftype {
57  { "Scid databases" {".si4"} }
58  { "PGN files" {".pgn" ".PGN"} }
59  }
60 
61  set fName [tk_getSaveFile \
62  -initialdir $::initialDir(base) \
63  -filetypes $ftype \
64  -defaultextension ".si4" \
65  -title "Create a Scid database"]
66 
67  if {$fName == ""} { return}
68  set file_extension [string tolower [file extension $fName]]
69  if {$file_extension == ".si4"} {
70  set dbType "SCID4"
71  set dbName [file rootname $fName]
72  } elseif {$file_extension == ".pgn"} {
73  set dbType "PGN"
74  set dbName $fName
75  }
76  if {[catch {sc_base create $dbType $dbName} baseId]} {
77  ERROR::MessageBox "$fName\n"
78  return
79  }
80  set ::curr_db $baseId
81  set ::initialDir(base) [file dirname $fName]
82  ::recentFiles::add $fName
85  return $baseId
86 }
87 
88 # ::file::Open
89 #
90 # Opens file-open dialog and opens the selected Scid database.
91 #
92 proc ::file::Open {{fName ""}} {
93  set err [::file::Open_ "$fName"]
94  if {$err == 0} {
95  set ::curr_db $::file::lastOpened
96  ::windows::gamelist::Open $::curr_db
98  foreach {tagname tagvalue} [sc_base extra $::curr_db] {
99  if {$tagname eq "autoload" && $tagvalue != 0} {
100  ::game::Load $tagvalue 0
101  break
102  }
103  }
105  }
106  return $err
107 }
108 
109 proc ::file::openBaseAsTree { { fName "" } } {
110  set current [sc_base current]
111  set err [::file::Open_ "$fName"]
112  sc_base switch $current
114  if {$err == 0} { ::tree::make $::file::lastOpened 1}
115  return $err
116 }
117 
118 proc ::file::Open_ {{fName ""} } {
119  if {$fName == ""} {
120  set ftype {
121  { "All Scid files" {".si4" ".si3" ".pgn" ".epd"} }
122  { "Scid databases, PGN files" {".si4" ".si3" ".pgn" ".PGN"} }
123  { "Scid databases" {".si4" ".si3"} }
124  { "PGN files" {".pgn" ".PGN"} }
125  { "EPD files" {".epd" ".EPD"} }
126  }
127 
128  set fName [tk_getOpenFile -initialdir $::initialDir(base) -filetypes $ftype -title "Open a Scid file"]
129  if {$fName == ""} { return 2}
130  }
131 
132  set ext [string tolower [file extension "$fName"]]
133  if {"$ext" == ".si4"} { set fName [file rootname "$fName"]}
134  if {[sc_base slot $fName] != 0} {
135  tk_messageBox -title "Scid: opening file" -message "The database you selected is already opened."
136  return 1
137  }
138 
139  set err 0
140  if {"$ext" == ".si3"} {
141  set err [::file::Upgrade [file rootname "$fName"]]
142  } elseif {"$ext" == ".pgn"} {
143  # PGN file:
144  progressWindow "Scid" "$::tr(OpeningTheDatabase): $fName..." $::tr(Cancel)
145  set err [catch {sc_base open PGN "$fName"} ::file::lastOpened]
147  if {$err} {
148  ERROR::MessageBox "$fName\n"
149  } else {
150  sc_base extra $::file::lastOpened type 3
151  set ::initialDir(base) [file dirname "$fName"]
152  ::recentFiles::add "$fName"
153  }
154  } elseif {"$ext" == ".epd"} {
155  # EPD file:
156  set err [catch {sc_base create MEMORY "$fName"} ::file::lastOpened]
157  if {$err} {
158  ERROR::MessageBox "$fName\n"
159  } else {
160  importPgnFile $::file::lastOpened [list "$fName"]
161  sc_base extra $::file::lastOpened type 3
162  set ::initialDir(base) [file dirname "$fName"]
163  ::recentFiles::add "$fName"
164  }
165  } elseif {"$ext" eq ".si4" || "$ext" eq ""} {
166  progressWindow "Scid" "$::tr(OpeningTheDatabase): [file tail "$fName"]..." $::tr(Cancel)
167  set err [catch {sc_base open "$fName"} ::file::lastOpened]
169  if {$err} {
170  if { $::errorCode == $::ERROR::NameDataLoss } { set err 0}
171  ERROR::MessageBox "$fName.si4\n"
172  } else {
173  set ::initialDir(base) [file dirname "$fName"]
174  ::recentFiles::add "$fName.si4"
175  }
176  } else {
177  tk_messageBox -title "Scid: opening file" -message "Unsupported database format: $ext"
178  set err 1
179  }
180 
181  return $err
182 }
183 
184 # ::file::Upgrade
185 #
186 # Upgrades an old (version 3) Scid database to version 4.
187 #
188 proc ::file::Upgrade {name} {
189  if {[file readable "$name.si4"]} {
190  set msg [string trim $::tr(ConfirmOpenNew)]
191  set res [tk_messageBox -title "Scid" -type yesno -icon info -message $msg]
192  if {$res == "no"} { return}
193  return [::file::Open_ "$name.si4"]
194  }
195 
196  set msg [string trim $::tr(ConfirmUpgrade)]
197  set res [tk_messageBox -title "Scid" -type yesno -icon info -message $msg]
198  if {$res == "no"} { return}
199 
200  set err [catch {
201  file copy "$name.sg3" "$name.sg4"
202  file copy "$name.sn3" "$name.sn4"
203  file copy "$name.si3" "$name.si4"}]
204  if {$err} {
205  ERROR::MessageBox "$name\n"
206  return 1
207  }
208 
209  progressWindow "Scid" "$::tr(Opening): [file tail $name]..." $::tr(Cancel)
210  set err [catch {sc_base open $name} ::file::lastOpened]
212  if {$::errorCode == $::ERROR::NameDataLoss} {
213  ERROR::MessageBox "$name\n"
214  set err 0
215  }
216  if {$err} {
217  ERROR::MessageBox "$name\n"
218  catch {
219  file delete "$name.sg4"
220  file delete "$name.sn4"
221  file delete "$name.si4"}
222  } else {
223  progressWindow "Scid" [concat $::tr(CompactDatabase) "..."] $::tr(Cancel)
224  set err_compact [catch {sc_base compact $::file::lastOpened}]
226  if {$err_compact} { ERROR::MessageBox}
227  }
228  return $err
229 }
230 
231 # ::file::Close:
232 # Closes the active base.
233 #
234 proc ::file::Close {{base -1}} {
235  # Remember the current base:
236  set current [sc_base current]
237  if {$base < 0} { set base $current}
238  if {![sc_base inUse $base]} { return}
239  # Switch to the base which will be closed, and check for changes:
240  sc_base switch $base
241  set confirm [::game::ConfirmDiscard]
242  if {$confirm == 0} {
243  sc_base switch $current
244  return
245  }
246  # Close Tree window whenever a base is closed/switched:
247  if {[winfo exists .treeWin$base]} { destroy .treeWin$base}
248 
250 
251  # If base to close was the current one, reset to clipbase
252  if { $current == $base } { set current 9}
253 
254  if {[catch {sc_base close $base}]} {
256  }
257 
258  if {$confirm == 2} { ::notify::DatabaseModified $::clipbase_db}
259 
260  # Now switch back to the original base
261  ::file::SwitchToBase $current 0
262 }
263 
264 proc ::file::SwitchToBase {{b} {saveHistory 1}} {
265  if {![catch {sc_base switch $b} res]} {
266  set ::curr_db $res
267  # Close email window when a base is switched:
268  if {[winfo exists .emailWin]} { destroy .emailWin}
269  }
272 }
273 
274 # Databases that will be automatically loaded ad startup
275 proc ::file::autoLoadBases.load {} {
276  if {![info exists ::autoLoadBases]} { return}
277  foreach base $::autoLoadBases {
278  if {[::file::Open $base] != 0} {
279  set idx [lsearch -exact $::autoLoadBases $base]
280  if {$idx != -1} { set ::autoLoadBases [lreplace $::autoLoadBases $idx $idx]}
281  }
282  }
283 }
284 
285 proc ::file::autoLoadBases.save { {channelId} } {
286  if {![info exists ::autoLoadBases]} { return}
287  puts $channelId "set ::autoLoadBases [list $::autoLoadBases]"
288 }
289 proc ::file::autoLoadBases.find { {baseIdx} } {
290  if {![info exists ::autoLoadBases]} { return -1}
291  if {[ catch {set base [sc_base filename $baseIdx]}]} { return -1}
292  return [lsearch -exact $::autoLoadBases $base]
293 }
294 proc ::file::autoLoadBases.add { {baseIdx} } {
295  if {[ catch {set base [sc_base filename $baseIdx]}]} { return}
296  lappend ::autoLoadBases $base
297 }
298 proc ::file::autoLoadBases.remove { {baseIdx} } {
299  if {![info exists ::autoLoadBases]} { return}
300  if {[ catch {set base [sc_base filename $baseIdx]}]} { return}
301  set idx [lsearch -exact $::autoLoadBases $base]
302  if {$idx != -1} {
303  set ::autoLoadBases [lreplace $::autoLoadBases $idx $idx]
304  }
305 }