Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
magicseteditor
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
magicseteditor
Commits
43d47e10
Commit
43d47e10
authored
Apr 19, 2007
by
twanvl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implemented apprentice export
parent
d302d206
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
800 additions
and
4 deletions
+800
-4
data/en.mse-locale/locale
data/en.mse-locale/locale
+9
-1
src/data/card.hpp
src/data/card.hpp
+10
-0
src/data/format/apprentice.cpp
src/data/format/apprentice.cpp
+777
-1
src/data/format/formats.hpp
src/data/format/formats.hpp
+3
-0
src/gui/set/window.cpp
src/gui/set/window.cpp
+1
-2
No files found.
data/en.mse-locale/locale
View file @
43d47e10
...
...
@@ -47,7 +47,7 @@ menu:
add
keyword
:
&
Add
Keyword
Ctrl
++
remove
keyword
:
&
Remove
Select
Keyword
Del
format
:
&
F
ormat
format
:
F
&
ormat
bold
:
&
Bold
Ctrl
+
B
italic
:
&
Italic
Ctrl
+
I
symbols
:
&
Symbols
Ctrl
+
M
...
...
@@ -161,6 +161,9 @@ help:
(
When
off
,
the
cards
are
exported
and
copied
at
100
%
size
and
normal
rotation
)
#
apprentice
export
set
code
:
A
set
code
is
a
two
character
code
that
is
used
by
Apprentice
to
refer
to
a
set
.
#
Symbol
editor
new
symbol
:
Create
a
new
symbol
open
symbol
:
Open
a
symbol
...
...
@@ -366,6 +369,10 @@ label:
cards
to
export
:
Cards
to
export
filename
is
ignored
:
(
filename
is
ignored
)
#
apprentice
export
set
code
:
Set
&
Code
:
apprentice
export
cancled
:
Export
to
Apprentice
is
cancled
#
Image
slicer
original
:
Original
:
result
:
Result
:
...
...
@@ -443,6 +450,7 @@ title:
print
preview
:
Print
Preview
#
export
export
images
:
Export
Images
export
cancled
:
Export
Cancled
##############################################################
Action
(
undo
/
redo
)
names
action
:
...
...
src/data/card.hpp
View file @
43d47e10
...
...
@@ -55,6 +55,16 @@ class Card {
}
throw
InternalError
(
_
(
"Expected a card field with name '"
)
+
name
+
_
(
"'"
));
}
template
<
typename
T
>
const
T
&
value
(
const
String
&
name
)
const
{
for
(
IndexMap
<
FieldP
,
ValueP
>::
const_iterator
it
=
data
.
begin
()
;
it
!=
data
.
end
()
;
++
it
)
{
if
((
*
it
)
->
fieldP
->
name
==
name
)
{
const
T
*
ret
=
dynamic_cast
<
const
T
*>
(
it
->
get
());
if
(
!
ret
)
throw
InternalError
(
_
(
"Card field with name '"
)
+
name
+
_
(
"' doesn't have the right type"
));
return
*
ret
;
}
}
throw
InternalError
(
_
(
"Expected a card field with name '"
)
+
name
+
_
(
"'"
));
}
DECLARE_REFLECTION
();
};
...
...
src/data/format/apprentice.cpp
View file @
43d47e10
...
...
@@ -7,5 +7,781 @@
// ----------------------------------------------------------------------------- : Includes
#include <data/format/formats.hpp>
#include <data/settings.hpp>
#include <data/set.hpp>
#include <data/game.hpp>
#include <data/card.hpp>
#include <data/field/text.hpp>
#include <data/field/choice.hpp>
#include <util/tagged_string.hpp>
#include <util/window_id.hpp>
#include <wx/progdlg.h>
#include <wx/wfstream.h>
#include <wx/datstrm.h>
#include <wx/filename.h>
// ----------------------------------------------------------------------------- :
DECLARE_TYPEOF_COLLECTION
(
String
);
DECLARE_TYPEOF_COLLECTION
(
CardP
);
DECLARE_TYPEOF
(
map
<
String
COMMA
String
>
);
String
card_rarity_code
(
const
String
&
rarity
);
// ----------------------------------------------------------------------------- : Generic export dialog
/// Callback for updating a progress bar
class
WithProgress
{
public:
virtual
void
onProgress
(
float
progress
,
const
String
&
message
)
=
0
;
};
/// Exception thrown to indicate exporting should be aborted
class
AbortException
{};
/// A dialog to show the progress of exporting
class
ExportProgressDialog
:
public
wxProgressDialog
,
public
WithProgress
{
public:
ExportProgressDialog
(
Window
*
parent
,
const
String
&
title
,
const
String
&
message
);
/// Update the progress bar
/** if the operation should be aborted, throws an AbortException
*/
virtual
void
onProgress
(
float
progress
,
const
String
&
message
);
};
ExportProgressDialog
::
ExportProgressDialog
(
Window
*
parent
,
const
String
&
title
,
const
String
&
message
)
:
wxProgressDialog
(
title
,
message
,
1000
,
parent
,
wxPD_APP_MODAL
|
wxPD_SMOOTH
|
wxPD_CAN_ABORT
)
{}
void
ExportProgressDialog
::
onProgress
(
float
progress
,
const
String
&
message
)
{
if
(
!
Update
(
int
(
progress
*
1000
),
message
))
{
throw
AbortException
();
}
}
// ----------------------------------------------------------------------------- : Generic apprentice database
/// An Apprentice database file, has read() and write() functions
class
ApprDatabase
{
public:
ApprDatabase
(
WithProgress
*
progress_target
,
const
String
&
name
);
~
ApprDatabase
();
/// Read the database
void
read
();
/// Write to a temporary file
void
write
();
/// Finalize the writing, swap the actual and the temporary file
void
commit
();
protected:
virtual
void
doRead
(
wxInputStream
&
)
=
0
;
virtual
void
doWrite
(
wxOutputStream
&
)
=
0
;
WithProgress
*
progress_target
;
///< Write progress information to here
private:
bool
in_progress
;
///< Is writing in progress?
String
filename
;
///< Filename of database file
};
ApprDatabase
::
ApprDatabase
(
WithProgress
*
progress_target
,
const
String
&
name
)
:
progress_target
(
progress_target
)
,
in_progress
(
false
)
,
filename
(
settings
.
apprentice_location
+
_
(
"
\\
"
)
+
name
)
{}
ApprDatabase
::~
ApprDatabase
()
{
// An exception is thrown while we were writing, clean up the temporary files
if
(
in_progress
)
{
// abort 'transaction'
wxRemoveFile
(
filename
+
_
(
".new"
));
}
}
void
ApprDatabase
::
read
()
{
wxFileInputStream
in
(
filename
);
if
(
!
in
.
Ok
())
{
throw
Error
(
_
(
"Can not open apprentice file for input
\n
'"
)
+
filename
+
_
(
"'"
));
}
doRead
(
in
);
}
void
ApprDatabase
::
write
()
{
// write to a .new file, doesn't commit yet
if
(
wxFileExists
(
filename
+
_
(
".new"
)))
{
wxRemoveFile
(
filename
+
_
(
".new"
));
}
wxFileOutputStream
out
(
filename
+
_
(
".new"
));
in_progress
=
true
;
if
(
!
out
.
Ok
())
{
throw
Error
(
_
(
"Can not open apprentice file for output
\n
'"
)
+
filename
+
_
(
".new'"
));
}
doWrite
(
out
);
}
void
ApprDatabase
::
commit
()
{
// commit : rename .new to real filename
if
(
in_progress
)
{
wxRenameFile
(
filename
,
filename
+
_
(
".bak"
));
wxRenameFile
(
filename
+
_
(
".new"
),
filename
);
in_progress
=
false
;
}
}
// ----------------------------------------------------------------------------- : Expansion database
/// An Apprentice expansion database (Expan.dat)
class
ApprExpansionDatabase
:
public
ApprDatabase
{
public:
inline
ApprExpansionDatabase
(
WithProgress
*
progress_target
)
:
ApprDatabase
(
progress_target
,
_
(
"Expan.dat"
))
{}
protected:
virtual
void
doRead
(
wxInputStream
&
in
);
virtual
void
doWrite
(
wxOutputStream
&
out
);
public:
map
<
String
,
String
>
expansions
;
///< code -> name
vector
<
String
>
order
;
///< order of codes
};
void
ApprExpansionDatabase
::
doRead
(
wxInputStream
&
in
)
{
wxTextInputStream
tin
(
in
);
while
(
!
in
.
Eof
())
{
String
l
=
tin
.
ReadLine
();
if
(
l
.
size
()
<
3
)
continue
;
order
.
push_back
(
l
.
substr
(
0
,
2
));
expansions
[
l
.
substr
(
0
,
2
)]
=
l
.
substr
(
3
);
}
}
void
ApprExpansionDatabase
::
doWrite
(
wxOutputStream
&
out
)
{
wxTextOutputStream
tout
(
out
,
wxEOL_DOS
);
// write in order first
FOR_EACH
(
c
,
order
)
{
String
code
=
c
;
if
(
code
.
GetChar
(
0
)
!=
_
(
'-'
))
{
// but not the rarities
tout
<<
code
<<
_
(
"-"
)
<<
expansions
[
c
]
<<
_
(
"
\n
"
);
expansions
.
erase
(
c
);
}
}
// the remaing expansions (our new set)
FOR_EACH
(
e
,
expansions
)
{
String
code
=
e
.
first
;
if
(
code
.
GetChar
(
0
)
!=
_
(
'-'
))
{
tout
<<
code
<<
_
(
"-"
)
<<
e
.
second
<<
_
(
"
\n
"
);
}
}
// and at last the rarities
FOR_EACH
(
c
,
order
)
{
String
code
=
c
;
if
(
code
.
GetChar
(
0
)
==
_
(
'-'
))
{
tout
<<
c
<<
_
(
"-"
)
<<
expansions
[
c
]
<<
_
(
"
\n
"
);
}
}
}
// ----------------------------------------------------------------------------- : Format database
class
ApprFormat
{
public:
ApprFormat
(
const
String
&
name
)
:
name
(
name
)
{}
String
name
,
sets
;
};
DECLARE_TYPEOF_COLLECTION
(
ApprFormat
);
/// An Apprentice format database (Format.dat)
class
ApprFormatDatabase
:
public
ApprDatabase
{
public:
inline
ApprFormatDatabase
(
WithProgress
*
progress_target
)
:
ApprDatabase
(
progress_target
,
_
(
"Format.dat"
))
{}
/// Remove a set code from all formats
void
removeSet
(
const
String
&
code
);
protected:
virtual
void
doRead
(
wxInputStream
&
in
);
virtual
void
doWrite
(
wxOutputStream
&
out
);
private:
vector
<
ApprFormat
>
formats
;
};
void
ApprFormatDatabase
::
removeSet
(
const
String
&
code
)
{
// TODO?
}
void
ApprFormatDatabase
::
doRead
(
wxInputStream
&
in
)
{
wxTextInputStream
tin
(
in
);
// read titles
while
(
!
in
.
Eof
())
{
String
l
=
trim
(
tin
.
ReadLine
());
if
(
l
==
_
(
"<Titles>"
))
{
// ignore header
}
else
if
(
l
==
_
(
"<Format>"
))
{
break
;
// to formatting step
}
else
{
size_t
pos
=
l
.
find_first_of
(
_
(
'='
));
if
(
pos
==
String
::
npos
)
continue
;
// assume formats are in order
formats
.
push_back
(
ApprFormat
(
l
.
substr
(
pos
+
1
))
);
}
}
// read formats
size_t
i
=
0
;
while
(
!
in
.
Eof
()
&&
i
<
formats
.
size
())
{
String
l
=
trim
(
tin
.
ReadLine
());
size_t
pos
=
l
.
find_first_of
(
_
(
'='
));
if
(
pos
==
String
::
npos
)
continue
;
formats
[
i
].
sets
=
l
.
substr
(
pos
+
1
);
i
+=
1
;
}
}
void
ApprFormatDatabase
::
doWrite
(
wxOutputStream
&
out
)
{
wxTextOutputStream
tout
(
out
,
wxEOL_DOS
);
tout
<<
_
(
"<Titles>
\n
"
);
int
i
=
1
;
FOR_EACH
(
f
,
formats
)
{
tout
<<
i
++
<<
_
(
"="
)
<<
f
.
name
<<
_
(
"
\n
"
);
}
tout
<<
_
(
"
\n
<Format>
\n
"
);
i
=
1
;
FOR_EACH
(
f
,
formats
)
{
tout
<<
i
++
<<
_
(
"="
)
<<
f
.
sets
<<
_
(
"
\n
"
);
}
}
// ----------------------------------------------------------------------------- : Distro database
// An entry in the Distro database
class
ApprDistro
{
public:
inline
ApprDistro
(
int
bc
=
0
,
int
bu
=
0
,
int
br
=
0
,
int
sc
=
0
,
int
su
=
0
,
int
sr
=
0
)
:
bc
(
bc
),
bu
(
bu
),
br
(
br
)
,
sc
(
sc
),
su
(
su
),
sr
(
sr
)
{}
int
bc
,
bu
,
br
;
///< # of cards in booster of each rarity
int
sc
,
su
,
sr
;
///< .. in starter
String
scode
,
bcode
;
///< alternative : numbers as a string (if numbers == 0)
void
write
(
const
String
&
code
,
wxTextOutputStream
&
tout
);
private:
void
writeD
(
wxTextOutputStream
&
tout
,
const
String
&
name
,
int
c
,
int
u
,
int
r
);
};
DECLARE_TYPEOF
(
map
<
String
COMMA
ApprDistro
>
);
/// An Apprentice distribution database (Distro.dat)
class
ApprDistroDatabase
:
public
ApprDatabase
{
public:
inline
ApprDistroDatabase
(
WithProgress
*
progress_target
)
:
ApprDatabase
(
progress_target
,
_
(
"Distro.dat"
))
{}
/// Remove a set code
void
removeSet
(
const
String
&
code
);
protected:
virtual
void
doRead
(
wxInputStream
&
in
);
virtual
void
doWrite
(
wxOutputStream
&
out
);
public:
map
<
String
,
ApprDistro
>
distros
;
vector
<
String
>
order
;
// order of codes
};
void
ApprDistroDatabase
::
removeSet
(
const
String
&
code
)
{
// TODO ?
}
void
ApprDistroDatabase
::
doRead
(
InputStream
&
in
)
{
wxTextInputStream
tin
(
in
);
ApprDistro
*
last
=
0
;
while
(
!
in
.
Eof
())
{
String
l
=
trim
(
tin
.
ReadLine
());
if
(
l
.
size
()
>
2
&&
l
.
GetChar
(
0
)
==
_
(
'<'
))
{
// new code
l
=
l
.
substr
(
1
,
l
.
size
()
-
2
);
order
.
push_back
(
l
);
last
=
&
distros
[
l
];
}
else
if
(
last
&&
starts_with
(
l
,
_
(
"Starter"
)))
{
// no need to read the actual code, only to write it out later
// keep it as a string
last
->
scode
=
l
;
}
else
if
(
last
&&
starts_with
(
l
,
_
(
"Booster"
)))
{
last
->
bcode
=
l
;
}
}
}
void
ApprDistroDatabase
::
doWrite
(
OutputStream
&
out
)
{
wxTextOutputStream
tout
(
out
,
wxEOL_DOS
);
// write in order
FOR_EACH
(
c
,
order
)
{
distros
[
c
].
write
(
c
,
tout
);
distros
.
erase
(
c
);
}
// remaining distros (the newly added one)
FOR_EACH
(
d
,
distros
)
{
d
.
second
.
write
(
d
.
first
,
tout
);
}
}
void
ApprDistro
::
write
(
const
String
&
code
,
wxTextOutputStream
&
tout
)
{
tout
.
WriteString
(
_
(
"<"
)
+
code
+
_
(
">
\n
"
));
// starter
if
(
sc
||
su
||
sr
)
{
writeD
(
tout
,
_
(
"Starter"
),
sc
,
su
,
sr
);
}
else
if
(
!
scode
.
empty
())
{
tout
.
WriteString
(
_
(
" "
)
+
scode
+
_
(
"
\n
"
));
}
// booster
if
(
bc
||
bu
||
br
)
{
writeD
(
tout
,
_
(
"Booster"
),
bc
,
bu
,
br
);
}
else
if
(
!
bcode
.
empty
())
{
tout
.
WriteString
(
_
(
" "
)
+
bcode
+
_
(
"
\n
"
));
}
}
void
ApprDistro
::
writeD
(
wxTextOutputStream
&
tout
,
const
String
&
name
,
int
c
,
int
u
,
int
r
)
{
tout
.
WriteString
(
_
(
" "
)
+
name
+
_
(
"=R"
)
<<
r
<<
_
(
",U"
)
<<
u
<<
_
(
",C"
)
<<
c
<<
_
(
"
\n
"
));
}
// ----------------------------------------------------------------------------- : Card database
/// Untag function for apprentice, replaces newlines with \r\n
String
untag_appr
(
const
String
&
s
)
{
return
replace_all
(
untag
(
s
),
_
(
"
\n
"
),
_
(
"
\r\n
"
));
}
DECLARE_POINTER_TYPE
(
ApprCardRecord
);
DECLARE_TYPEOF_COLLECTION
(
ApprCardRecordP
);
/// An Apprentice card database (cardinfo.dat)
class
ApprCardDatabase
:
public
ApprDatabase
{
public:
inline
ApprCardDatabase
(
WithProgress
*
progress_target
)
:
ApprDatabase
(
progress_target
,
_
(
"sets
\\
cardinfo.dat"
))
{}
/// Remove a set code
void
removeSet
(
const
String
&
code
);
protected:
virtual
void
doRead
(
wxInputStream
&
in
);
virtual
void
doWrite
(
wxOutputStream
&
out
);
public:
vector
<
ApprCardRecordP
>
cards
;
};
/// A single record in the apprentice card database
/** Each card has two records, a data record at the top of the file
* and a head record at the bottom
*/
class
ApprCardRecord
{
public:
String
name
,
sets
;
String
type
,
cc
,
pt
,
text
,
flavor
;
UInt
data_pos
;
Byte
color
;
// bitmask:
enum
Color
{
white
=
0x01
,
blue
=
0x02
,
black
=
0x04
,
red
=
0x08
,
green
=
0x10
,
gold
=
0x20
,
arti
=
0x40
,
land
=
0x80
,
};
ApprCardRecord
()
{}
ApprCardRecord
(
const
Card
&
card
,
const
String
&
sets_
);
void
readHead
(
wxDataInputStream
&
strm
);
void
readCard
(
wxDataInputStream
&
strm
);
void
writeHead
(
wxDataOutputStream
&
strm
);
void
writeCard
(
wxDataOutputStream
&
strm
);
/// Reads a string in apprentice format
String
readString
(
wxDataInputStream
&
strm
);
/// Writes a string in apprentice format
void
writeString
(
wxDataOutputStream
&
strm
,
const
String
&
out
);
// Remove a code from the list of set codes
void
removeSet
(
const
String
&
code
);
};
// conversion from MSE2 card
ApprCardRecord
::
ApprCardRecord
(
const
Card
&
card
,
const
String
&
sets_
)
{
name
=
untag_appr
(
card
.
value
<
TextValue
>
(
_
(
"name"
)).
value
);
sets
=
sets_
+
_
(
"-"
)
+
card_rarity_code
(
card
.
value
<
ChoiceValue
>
(
_
(
"rarity"
)).
value
);
cc
=
untag_appr
(
card
.
value
<
TextValue
>
(
_
(
"casting cost"
)).
value
);
type
=
untag_appr
(
card
.
value
<
TextValue
>
(
_
(
"super type"
)).
value
);
String
subType
=
untag
(
card
.
value
<
TextValue
>
(
_
(
"sub type"
)).
value
);
if
(
!
subType
.
empty
())
type
+=
_
(
" - "
)
+
subType
;
text
=
untag_appr
(
card
.
value
<
TextValue
>
(
_
(
"rule text"
)).
value
);
flavor
=
untag_appr
(
card
.
value
<
TextValue
>
(
_
(
"flavor text"
)).
value
);
pt
=
untag_appr
(
card
.
value
<
TextValue
>
(
_
(
"pt"
)).
value
);
}
void
ApprCardRecord
::
readHead
(
wxDataInputStream
&
strm
)
{
name
=
readString
(
strm
);
data_pos
=
strm
.
Read32
();
color
=
strm
.
Read8
();
sets
=
readString
(
strm
);
strm
.
Read16
();
// 00 00
}
void
ApprCardRecord
::
readCard
(
wxDataInputStream
&
strm
)
{
type
=
readString
(
strm
);
cc
=
readString
(
strm
);
pt
=
readString
(
strm
);
text
=
readString
(
strm
);
flavor
=
readString
(
strm
);
}
void
ApprCardRecord
::
writeHead
(
wxDataOutputStream
&
strm
)
{
name
=
name
.
substr
(
0
,
27
);
// max length
// determine color
color
=
0
;
int
cnt
=
0
;
if
(
cc
.
find_first_of
(
_
(
'W'
))
!=
String
::
npos
)
{
cnt
+=
1
;
color
|=
white
;
}
if
(
cc
.
find_first_of
(
_
(
'U'
))
!=
String
::
npos
)
{
cnt
+=
1
;
color
|=
blue
;
}
if
(
cc
.
find_first_of
(
_
(
'B'
))
!=
String
::
npos
)
{
cnt
+=
1
;
color
|=
black
;
}
if
(
cc
.
find_first_of
(
_
(
'R'
))
!=
String
::
npos
)
{
cnt
+=
1
;
color
|=
red
;
}
if
(
cc
.
find_first_of
(
_
(
'G'
))
!=
String
::
npos
)
{
cnt
+=
1
;
color
|=
green
;
}
if
(
cnt
>
1
)
color
|=
gold
;
if
(
cnt
==
0
)
{
if
(
type
.
find
(
_
(
"Land"
))
!=
String
::
npos
)
color
=
land
;
else
color
=
arti
;
}
// write
writeString
(
strm
,
name
);
strm
.
Write32
(
data_pos
);
strm
.
Write8
(
color
);
writeString
(
strm
,
sets
);
strm
.
Write16
(
0x0000
);
}
void
ApprCardRecord
::
writeCard
(
wxDataOutputStream
&
strm
)
{
writeString
(
strm
,
type
);
writeString
(
strm
,
cc
);
writeString
(
strm
,
pt
);
writeString
(
strm
,
text
);
writeString
(
strm
,
flavor
);
}
String
ApprCardRecord
::
readString
(
wxDataInputStream
&
strm
)
{
size_t
size
=
strm
.
Read16
();
if
(
size
>
1000
)
size
=
1000
;
// sanity check
String
ret
;
ret
.
reserve
(
size
);
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
ret
+=
(
Char
)
strm
.
Read8
();
}
return
ret
;
}
void
ApprCardRecord
::
writeString
(
wxDataOutputStream
&
strm
,
const
String
&
out
)
{
strm
.
Write16
(
UInt
(
out
.
size
()));
FOR_EACH_CONST
(
c
,
out
)
{
strm
.
Write8
(
c
);
}
}
void
ApprCardRecord
::
removeSet
(
const
String
&
code
)
{
size_t
pos
=
sets
.
find
(
code
);
if
(
pos
==
String
::
npos
)
return
;
String
before
=
sets
.
substr
(
0
,
pos
);
String
after
=
sets
.
substr
(
pos
+
code
.
size
());
if
(
!
before
.
empty
()
&&
before
.
GetChar
(
before
.
size
()
-
1
)
==
_
(
','
))
{
// remove comma
before
.
resize
(
before
.
size
()
-
1
);
}
sets
=
before
+
after
;
}
// Is a card record unused, i.e. no sets refer to it?
bool
unused_appr_card_record
(
const
ApprCardRecordP
&
rec
)
{
return
rec
->
sets
.
size
()
<
2
||
// nothing
(
rec
->
sets
.
size
()
<
4
&&
rec
->
sets
.
find_first_of
(
_
(
'-'
))
!=
String
::
npos
);
// only a rarity code
}
void
ApprCardDatabase
::
removeSet
(
const
String
&
code
)
{
FOR_EACH
(
c
,
cards
)
{
c
->
removeSet
(
code
);
}
// cleanup
cards
.
erase
(
remove_if
(
cards
.
begin
(),
cards
.
end
(),
unused_appr_card_record
),
cards
.
end
());
}
void
ApprCardDatabase
::
doRead
(
wxInputStream
&
in
)
{
wxDataInputStream
data
(
in
);
size_t
head_pos
=
data
.
Read32
();
in
.
SeekI
(
head_pos
);
size_t
card_count
=
data
.
Read32
();
cards
.
resize
(
card_count
);
// read cards
int
i
=
0
;
FOR_EACH
(
card
,
cards
)
{
if
(
++
i
%
100
==
0
)
{
// report progress sometimes
progress_target
->
onProgress
(
0.4
f
*
float
(
i
)
/
cards
.
size
(),
String
(
_
(
"reading card "
))
<<
i
<<
_
(
" of "
)
<<
(
int
)
cards
.
size
());
}
card
=
new_shared
<
ApprCardRecord
>
();
card
->
readHead
(
data
);
head_pos
=
in
.
TellI
();
in
.
SeekI
(
card
->
data_pos
);
card
->
readCard
(
data
);
in
.
SeekI
(
head_pos
);
}
}
void
ApprCardDatabase
::
doWrite
(
wxOutputStream
&
out
)
{
wxDataOutputStream
data
(
out
);
data
.
Write32
(
0
);
// replaced with header pos
// write card data
int
i
=
0
;
FOR_EACH
(
card
,
cards
)
{
if
(
++
i
%
100
==
0
)
{
// report progress sometimes
progress_target
->
onProgress
(
0.4
f
+
0.4
f
*
float
(
i
)
/
cards
.
size
(),
String
(
_
(
"writing card "
))
<<
i
<<
_
(
" of "
)
<<
(
int
)
cards
.
size
());
}
card
->
data_pos
=
out
.
TellO
();
card
->
writeCard
(
data
);
}
// write header location
UInt
head_start
=
out
.
TellO
();
out
.
SeekO
(
0
);
data
.
Write32
(
head_start
);
// card count
out
.
SeekO
(
head_start
);
data
.
Write32
((
UInt
)
cards
.
size
());
// write card heads
i
=
0
;
FOR_EACH
(
card
,
cards
)
{
if
(
++
i
%
100
==
0
)
{
// report progress sometimes
progress_target
->
onProgress
(
0.8
f
+
0.2
f
*
float
(
i
)
/
cards
.
size
(),
String
(
_
(
"writing header "
))
<<
i
<<
_
(
" of "
)
<<
(
int
)
cards
.
size
());
}
card
->
writeHead
(
data
);
}
}
// ----------------------------------------------------------------------------- : Export dialog
/// Dialog for exporting a set to Apprentice
class
ApprenticeExportWindow
:
public
wxDialog
,
public
WithProgress
{
public:
ApprenticeExportWindow
(
Window
*
parent
,
const
SetP
&
set
);
virtual
void
onProgress
(
float
p
,
const
String
&
message
);
void
doStep
(
const
String
&
s
,
float
size
);
private:
DECLARE_EVENT_TABLE
();
SetP
set
;
// Gui controls
wxTextCtrl
*
apprentice
,
*
set_code
;
// In what step of the export process are we?
String
step
;
float
step_begin
,
step_end
;
ExportProgressDialog
*
progress_target
;
void
onApprenticeBrowse
(
wxCommandEvent
&
ev
);
void
onOk
(
wxCommandEvent
&
ev
);
/// Export the set
bool
export
();
};
void
export_apprentice
(
Window
*
parent
,
const
SetP
&
set
)
{
ApprenticeExportWindow
wnd
(
parent
,
set
);
wnd
.
ShowModal
();
}
ApprenticeExportWindow
::
ApprenticeExportWindow
(
Window
*
parent
,
const
SetP
&
set
)
:
wxDialog
(
parent
,
wxID_ANY
,
_
(
"Export to Apprentice"
),
wxDefaultPosition
)
,
set
(
set
)
,
step_begin
(
0
),
step_end
(
0
)
{
if
(
!
set
->
game
->
isMagic
())
throw
Error
(
_
(
"Can only export Magic sets to Apprentice"
));
// create controls
apprentice
=
new
wxTextCtrl
(
this
,
wxID_ANY
);
set_code
=
new
wxTextCtrl
(
this
,
wxID_ANY
);
wxButton
*
browse
=
new
wxButton
(
this
,
ID_APPRENTICE_BROWSE
,
_BUTTON_
(
"browse"
));
// set values
apprentice
->
SetValue
(
settings
.
apprentice_location
);
set_code
->
SetValue
(
set
->
apprentice_code
);
// init sizer
wxSizer
*
s
=
new
wxBoxSizer
(
wxVERTICAL
);
// Apprentice location
s
->
Add
(
new
wxStaticText
(
this
,
wxID_ANY
,
_TITLE_
(
"locate apprentice"
)),
0
,
wxALL
,
4
);
wxSizer
*
s2
=
new
wxBoxSizer
(
wxHORIZONTAL
);
s2
->
Add
(
apprentice
,
1
,
wxEXPAND
|
wxRIGHT
,
4
);
s2
->
Add
(
browse
,
0
,
wxEXPAND
);
s
->
Add
(
s2
,
0
,
wxEXPAND
|
wxALL
&
~
wxTOP
,
4
);
s
->
AddSpacer
(
8
);
// Set code
s
->
Add
(
new
wxStaticText
(
this
,
-
1
,
_LABEL_
(
"set code"
)),
0
,
wxALL
,
4
);
s
->
Add
(
set_code
,
0
,
wxEXPAND
|
wxLEFT
|
wxRIGHT
,
4
);
s
->
Add
(
new
wxStaticText
(
this
,
-
1
,
_HELP_
(
"set code"
)),
0
,
wxALL
,
4
);
s
->
AddSpacer
(
4
);
s
->
Add
(
CreateButtonSizer
(
wxOK
|
wxCANCEL
),
0
,
wxEXPAND
|
wxALL
&
~
wxTOP
,
8
);
s
->
SetSizeHints
(
this
);
SetSizer
(
s
);
}
void
ApprenticeExportWindow
::
onApprenticeBrowse
(
wxCommandEvent
&
ev
)
{
// browse for appr.exe
// same as in DirsPreferencesPage
wxFileDialog
dlg
(
this
,
_TITLE_
(
"locate apprentice"
),
apprentice
->
GetValue
(),
_
(
""
),
_LABEL_
(
"apprentice exe"
)
+
_
(
"|appr.exe"
),
wxOPEN
);
if
(
dlg
.
ShowModal
()
==
wxID_OK
)
{
wxFileName
fn
(
dlg
.
GetPath
());
apprentice
->
SetValue
(
fn
.
GetPath
());
}
}
void
ApprenticeExportWindow
::
onOk
(
wxCommandEvent
&
ev
)
{
// store settings
settings
.
apprentice_location
=
apprentice
->
GetValue
();
// store new code
String
new_set_code
=
set_code
->
GetValue
();
if
(
new_set_code
.
size
()
!=
2
)
{
wxMessageBox
(
_
(
"The set code must be 2 characters long"
),
_
(
"Invalid set code"
),
wxOK
|
wxICON_ERROR
);
return
;
}
new_set_code
.
MakeUpper
();
set
->
apprentice_code
.
MakeUpper
();
if
(
set
->
apprentice_code
!=
new_set_code
)
{
// changed something in the set
set
->
apprentice_code
=
new_set_code
;
//%%set->actions.atSavePoint = false; // tell the user he needs to save
}
// Check if apprentice exists
if
(
!
wxFileExists
(
settings
.
apprentice_location
+
_
(
"
\\
appr.exe"
)))
{
wxMessageBox
(
_
(
"Apprentice is not found in the specified location
\n
"
)
+
settings
.
apprentice_location
,
_
(
"Apprentice Not Found"
),
wxOK
|
wxICON_ERROR
);
return
;
}
// create progress dialog
progress_target
=
new
ExportProgressDialog
(
this
,
_
(
"Export to Apprentice"
),
_
(
"Exporting to Apprentice, please wait"
));
progress_target
->
Show
();
// export!
try
{
if
(
!
export
())
{
// canceled, but allow to try again
progress_target
->
Hide
();
progress_target
->
Close
();
return
;
}
}
catch
(
const
AbortException
&
)
{
// aborted, cleanup is already handled by dtors
wxMessageBox
(
_LABEL_
(
"apprentice export cancled"
),
_TITLE_
(
"export canceled"
),
wxOK
|
wxICON_INFORMATION
);
}
// Done, close progress window
progress_target
->
Hide
();
progress_target
->
Close
();
// Close this window
EndModal
(
wxID_OK
);
}
bool
ApprenticeExportWindow
::
export
()
{
// Expan database
doStep
(
_
(
"Exporting expansion"
),
0.01
f
);
ApprExpansionDatabase
expan
(
this
);
expan
.
read
();
// Is there already a set with the desired code?
map
<
String
,
String
>::
iterator
expan_it
=
expan
.
expansions
.
find
(
set
->
apprentice_code
);
if
(
expan_it
!=
expan
.
expansions
.
end
())
{
int
res
=
wxMessageBox
(
_
(
"There is already a set with the code '"
)
+
expan_it
->
first
+
_
(
"' in the Apprentice database.
\n
"
)
+
_
(
"This set has the name '"
)
+
expan_it
->
second
+
_
(
"'
\n
"
)
+
_
(
"Do you want to continue, and overwrite that set?"
),
_
(
"Overwrite Set?"
),
wxYES_NO
|
wxICON_EXCLAMATION
);
if
(
res
==
wxNO
)
return
false
;
// abort export
}
// add our set
expan
.
expansions
[
set
->
apprentice_code
]
=
set
->
value
<
TextValue
>
(
_
(
"title"
)).
value
;
expan
.
write
();
// Format database
doStep
(
_
(
"Exporting format"
),
0.01
f
);
ApprFormatDatabase
format
(
this
);
format
.
read
();
// remove old with code, TODO add new?
format
.
removeSet
(
set
->
apprentice_code
);
format
.
write
();
// Distro database
doStep
(
_
(
"Exporting distribution"
),
0.01
f
);
ApprDistroDatabase
distro
(
this
);
distro
.
read
();
// remove old with code, add new
distro
.
removeSet
(
set
->
apprentice_code
);
distro
.
distros
[
set
->
apprentice_code
]
=
ApprDistro
(
11
,
3
,
1
);
// booster size
distro
.
write
();
// Card database
doStep
(
_
(
"Exporting cards"
),
0.96
f
);
ApprCardDatabase
cardlist
(
this
);
cardlist
.
read
();
// remove old cards with same code
cardlist
.
removeSet
(
set
->
apprentice_code
);
// add cards from set
FOR_EACH
(
card
,
set
->
cards
)
{
ApprCardRecordP
rec
=
new_shared2
<
ApprCardRecord
>
(
*
card
,
set
->
apprentice_code
);
cardlist
.
cards
.
push_back
(
rec
);
}
cardlist
.
write
();
// Commit everything
doStep
(
_
(
"Committing"
),
0.01
f
);
expan
.
commit
();
format
.
commit
();
distro
.
commit
();
cardlist
.
commit
();
return
true
;
// all went well
}
void
ApprenticeExportWindow
::
onProgress
(
float
p
,
const
String
&
m
)
{
progress_target
->
onProgress
(
p
*
(
step_end
-
step_begin
)
+
step_begin
,
m
.
empty
()
?
step
:
step
+
_
(
": "
)
+
m
);
}
void
ApprenticeExportWindow
::
doStep
(
const
String
&
s
,
float
size
)
{
step
=
s
;
step_begin
=
step_end
;
step_end
+=
size
;
onProgress
(
0.0
f
,
_
(
""
));
}
BEGIN_EVENT_TABLE
(
ApprenticeExportWindow
,
wxDialog
)
EVT_BUTTON
(
wxID_OK
,
ApprenticeExportWindow
::
onOk
)
EVT_BUTTON
(
ID_APPRENTICE_BROWSE
,
ApprenticeExportWindow
::
onApprenticeBrowse
)
END_EVENT_TABLE
()
src/data/format/formats.hpp
View file @
43d47e10
...
...
@@ -94,5 +94,8 @@ Bitmap export_bitmap(const SetP& set, const CardP& card);
/// Export a set to Magic Workstation format
void
export_mws
(
Window
*
parent
,
const
SetP
&
set
);
/// Export a set to Apprentice
void
export_apprentice
(
Window
*
parent
,
const
SetP
&
set
);
// ----------------------------------------------------------------------------- : EOF
#endif
src/gui/set/window.cpp
View file @
43d47e10
...
...
@@ -458,8 +458,7 @@ void SetWindow::onFileExportHTML(wxCommandEvent&) {
}
void
SetWindow
::
onFileExportApprentice
(
wxCommandEvent
&
)
{
// ApprenticeExportWindow wnd(&this, set);
// wnd.ShowModal();
export_apprentice
(
this
,
set
);
}
void
SetWindow
::
onFileExportMWS
(
wxCommandEvent
&
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment