Source Code (Use browser search to find items of interest.)
Class Index
kmahjongg'Preview (./kdegames/kmahjongg/Preview.h:44)
class Preview: public QDialog
{
Q_OBJECT
public:
enum PreviewType {background, tileset, board, theme};
Preview
(
QWidget* parent = NULL,
const char* name = NULL
);
virtual ~Preview();
void initialise(const PreviewType type, const char *extension);
void saveTheme(void);
protected:
void markUnchanged(void);
void markChanged(void);
bool isChanged(void);
QPixmap *getPreviewPixmap(void) {return drawFrame->getPreviewPixmap();};
virtual void drawPreview(void);
void applyChange(void) ;
void renderBackground(const char *bg);
void renderTiles(const char *file, const char *layout);
void paintEvent( QPaintEvent* pa );
signals:
void boardRedraw(bool);
void loadTileset(const char *);
void loadBackground(const char *, bool);
void loadBoard(const char *);
void layoutChange(void);
public slots:
void selectionChanged(int which);
protected slots:
private slots:
void apply(void);
void ok(void);
void load(void);
protected:
FrameImage * drawFrame;
QPushButton* cancelButton;
QPushButton* applyButton;
QPushButton* okButton;
QPushButton* loadButton;
QComboBox* combo;
QButtonGroup* topGroup;
QButtonGroup* bottomGroup;
QString selectedFile;
Tileset tiles;
BoardLayout boardLayout;
Background back;
private:
void parseFile(const char *f, QString &g);
QString fileSelector;
bool changed;
QFileInfoList fileList;
PreviewType previewType;
QString themeBack;
QString themeLayout;
QString themeTileset;
};
kmahjongg'Preview::Preview() (./kdegames/kmahjongg/Preview.cpp:26)
Preview::Preview
(
QWidget* parent,
const char* name
)
:
QDialog( parent, name, TRUE, 0 ), tiles(true)
{
const int dx=0;
const int dy = 66;
bottomGroup = new QButtonGroup( this, "bottomGroup" );
bottomGroup->setGeometry( 10, 230+dy, 310+dx, 50 );
bottomGroup->setMinimumSize( 0, 0 );
bottomGroup->setMaximumSize( 32767, 32767 );
bottomGroup->setFocusPolicy( QWidget::NoFocus );
bottomGroup->setBackgroundMode( QWidget::PaletteBackground );
bottomGroup->setFontPropagation( QWidget::NoChildren );
bottomGroup->setPalettePropagation( QWidget::NoChildren );
bottomGroup->setFrameStyle( 49 );
bottomGroup->setTitle( "" );
bottomGroup->setAlignment( 1 );
topGroup = new QButtonGroup( this, "topGroup" );
topGroup->setGeometry( 10, 10, 310+dx, 50);
topGroup->setMinimumSize( 0, 0 );
topGroup->setMaximumSize( 32767, 32767 );
topGroup->setFocusPolicy( QWidget::NoFocus );
topGroup->setBackgroundMode( QWidget::PaletteBackground );
topGroup->setFontPropagation( QWidget::NoChildren );
topGroup->setPalettePropagation( QWidget::NoChildren );
topGroup->setFrameStyle( 49 );
topGroup->setTitle( "" );
topGroup->setAlignment( 1 );
combo = new QComboBox( FALSE, this, "combo" );
combo->setGeometry( 20, 20, 220+dx, 25 );
combo->setMinimumSize( 0, 0 );
combo->setMaximumSize( 32767, 32767 );
combo->setFocusPolicy( QWidget::StrongFocus );
combo->setBackgroundMode( QWidget::PaletteBackground );
combo->setFontPropagation( QWidget::AllChildren );
combo->setPalettePropagation( QWidget::AllChildren );
combo->setSizeLimit( 10 );
combo->setAutoResize( FALSE );
connect( combo, SIGNAL(activated(int)), SLOT(selectionChanged(int)) );
loadButton = new QPushButton( this, "loadButton" );
loadButton->setGeometry( 250+dx, 20, 61, 26 );
loadButton->setMinimumSize( 0, 0 );
loadButton->setMaximumSize( 32767, 32767 );
connect( loadButton, SIGNAL(clicked()), SLOT(load()) );
loadButton->setFocusPolicy( QWidget::TabFocus );
loadButton->setBackgroundMode( QWidget::PaletteBackground );
loadButton->setFontPropagation( QWidget::NoChildren );
loadButton->setPalettePropagation( QWidget::NoChildren );
loadButton->setText(i18n("Load"));
loadButton->setAutoRepeat( FALSE );
loadButton->setAutoResize( FALSE );
// total w - button tot wid /4 (space left)
int bw = ((310+dx) - ((90+(dx/3))*3))/4 ;
int pos = bw +10;
okButton = new QPushButton( this, "okButton" );
okButton->setGeometry( pos, 240+dy, 90+(dx/3), 26 ); // was 20
okButton->setMinimumSize( 0, 0 );
okButton->setMaximumSize( 32767, 32767 );
connect( okButton, SIGNAL(clicked()), SLOT(ok()) );
okButton->setFocusPolicy( QWidget::TabFocus );
okButton->setBackgroundMode( QWidget::PaletteBackground );
okButton->setFontPropagation( QWidget::NoChildren );
okButton->setPalettePropagation( QWidget::NoChildren );
okButton->setText( i18n("OK") );
okButton->setAutoRepeat( FALSE );
okButton->setAutoResize( FALSE );
pos += (90+(dx/3))+bw;
applyButton = new QPushButton( this, "applyButton" );
applyButton->setGeometry( pos, 240+dy, 90+(dx/3), 26 );
applyButton->setMinimumSize( 0, 0 );
applyButton->setMaximumSize( 32767, 32767 );
connect( applyButton, SIGNAL(clicked()), SLOT(apply()) );
applyButton->setFocusPolicy( QWidget::TabFocus );
applyButton->setBackgroundMode( QWidget::PaletteBackground );
applyButton->setFontPropagation( QWidget::NoChildren );
applyButton->setPalettePropagation( QWidget::NoChildren );
applyButton->setText( i18n("Apply") );
applyButton->setAutoRepeat( FALSE );
applyButton->setAutoResize( FALSE );
pos += (90+(dx/3))+bw;
cancelButton = new QPushButton( this, "cancelButton" );
cancelButton->setGeometry( pos, 240+dy, 90+(dx/3), 26 );
cancelButton->setMinimumSize( 0, 0 );
cancelButton->setMaximumSize( 32767, 32767 );
connect( cancelButton, SIGNAL(clicked()), SLOT(reject()) );
cancelButton->setFocusPolicy( QWidget::TabFocus );
cancelButton->setBackgroundMode( QWidget::PaletteBackground );
cancelButton->setFontPropagation( QWidget::NoChildren );
cancelButton->setPalettePropagation( QWidget::NoChildren );
cancelButton->setText( i18n("Cancel") );
cancelButton->setAutoRepeat( FALSE );
cancelButton->setAutoResize( FALSE );
drawFrame = new FrameImage( this, "drawFrame" );
drawFrame->setGeometry( 10, 60, 310+dx, 170+dy );
drawFrame->setMinimumSize( 0, 0 );
drawFrame->setMaximumSize( 32767, 32767 );
drawFrame->setFocusPolicy( QWidget::NoFocus );
drawFrame->setBackgroundMode( QWidget::PaletteBackground );
drawFrame->setFontPropagation( QWidget::NoChildren );
drawFrame->setPalettePropagation( QWidget::NoChildren );
drawFrame->setFrameStyle( 49 );
bottomGroup->insert( okButton );
bottomGroup->insert( applyButton );
bottomGroup->insert( cancelButton );
topGroup->insert( loadButton );
resize( 330+dx, 290+dy );
setMinimumSize( 330+dx, 290+dy );
setMaximumSize( 330+dx, 290+dy );
changed = false;
}
kmahjongg'Preview::~Preview() (./kdegames/kmahjongg/Preview.cpp:156)
Preview::~Preview()
{
}
kmahjongg'Preview::selectionChanged() (./kdegames/kmahjongg/Preview.cpp:160)
void Preview::selectionChanged(int which) {
QFileInfo *f= fileList.at(which);
selectedFile = f->filePath();
drawPreview();
drawFrame->repaint(0,0,-1,-1,false);
markChanged();
}
kmahjongg'Preview::isChanged() (./kdegames/kmahjongg/Preview.cpp:169)
bool Preview::isChanged(void)
{
return changed;
}
kmahjongg'Preview::markChanged() (./kdegames/kmahjongg/Preview.cpp:174)
void Preview::markChanged(void)
{
changed = true;
}
kmahjongg'Preview::markUnchanged() (./kdegames/kmahjongg/Preview.cpp:179)
void Preview::markUnchanged(void)
{
changed = false;
}
kmahjongg'Preview::initialise() (./kdegames/kmahjongg/Preview.cpp:184)
void Preview::initialise(const PreviewType type, const char *extension)
{
// set up the concept of the current file. Initialised to the preferences
// value initially. Set the caption to indicate what we are doing
switch (type) {
case background:
setCaption(i18n("Change background image"));
selectedFile = preferences.background();
fileSelector = i18n("*.bgnd|Background Image\n"
"*.bmp|Windows bitmap file (*.bmp)\n");
break;
case tileset:
setCaption(i18n("Change tile set"));
fileSelector = i18n("*.tileset|Tile set file\n");
selectedFile = preferences.tileset();
break;
case board:
fileSelector = i18n("*.layout|Board layout file\n");
setCaption(i18n("Change board layout"));
selectedFile = preferences.layout();
break;
case theme:
fileSelector = i18n("*.theme|Kmahjongg theme\n");
setCaption(i18n("Choose a theme"));
selectedFile="";
themeLayout="";
themeBack="";
themeTileset="";
default:
break;
}
fileSelector += i18n("*.*|All files\n");
applyButton->setEnabled(type != board);
previewType = type;
// we start with no change indicated
markUnchanged();
QString kmDir;
QDir files;
QFileInfo *current=new QFileInfo(selectedFile);
bool oneFound = false;
// we pick up system files from the kde dir
kmDir = locate("appdata", "pics/default.tileset");
QFileInfo f(kmDir);
kmDir = f.dirPath();
files.cd(kmDir);
files.setNameFilter(extension);
files.setFilter(QDir::Files | QDir::Readable);
// get rid of files from the last invocation
fileList.clear();
// deep copy the file list as we need to keen to keep it
QFileInfoList *list = (QFileInfoList *) files.entryInfoList();
// put the curent entry in the returned list to test for
// duplicates on insertion
list->insert(0, current);
QFileInfo *info=list->first();
for (unsigned int p=0; p<list->count(); p++) {
if (fileList.find(info) == -1) {
fileList.append( new QFileInfo(*info));
}
info=list->next();
}
// copy the file basenames into the combo box
combo->clear();
if (fileList.count() >0) {
QFileInfo *cur=fileList.first();
for (unsigned int each=0; each < fileList.count(); each++) {
combo->insertItem(cur->baseName());
cur = fileList.next();
}
oneFound = true;
}
combo->setEnabled(oneFound);
drawPreview();
}
kmahjongg'Preview::apply() (./kdegames/kmahjongg/Preview.cpp:272)
void Preview::apply(void) {
if (isChanged()) {
applyChange();
markUnchanged();
}
}
kmahjongg'Preview::ok() (./kdegames/kmahjongg/Preview.cpp:279)
void Preview::ok(void) {
apply();
accept();
}
kmahjongg'Preview::load() (./kdegames/kmahjongg/Preview.cpp:284)
void Preview::load(void) {
KURL url = KFileDialog::getOpenURL(
NULL,
fileSelector,
this,
i18n("Open board layout." ));
if ( !url.isEmpty() ) {
selectedFile = url.path();
drawPreview();
drawFrame->repaint(0,0,-1,-1,false);
markChanged();
}
}
// Top level preview drawing method. Background, tileset and layout
// are initialised from the preferences. Depending on the type
// of preview dialog we pick up the selected file for one of these
// chaps.
kmahjongg'Preview::drawPreview() (./kdegames/kmahjongg/Preview.cpp:303)
void Preview::drawPreview(void) {
QString back = preferences.background();
QString tile = preferences.tileset();
QString layout = preferences.layout();
switch (previewType) {
case background:
back = selectedFile;
break;
case tileset:
tile = selectedFile;
break;
case board:
layout = selectedFile;
break;
case theme:
// a theme is quite a bit of work. We load the
// specified bits in (layout, background and tileset
if (selectedFile != "") {
char backRaw[MAXPATHLEN];
char layoutRaw[MAXPATHLEN];
char tilesetRaw[MAXPATHLEN];
char magic[MAXPATHLEN];
QFile in(selectedFile);
if (in.open(IO_ReadOnly)){
in.readLine(magic, MAXPATHLEN);
if (magic[strlen(magic)-1]=='\n')
magic[strlen(magic)-1]='\0';
if (strncmp(themeMagicV1_0, magic, strlen(magic)) != 0) {
in.close();
KMessageBox::sorry(this,
i18n("Thats not a valid theme file."));
break;
}
in.readLine(tilesetRaw, MAXPATHLEN);
in.readLine(backRaw, MAXPATHLEN);
in.readLine(layoutRaw, MAXPATHLEN);
parseFile(tilesetRaw, tile);
parseFile(backRaw, back);
parseFile(layoutRaw, layout);
in.close();
themeBack=back;
themeLayout=layout;
themeTileset=tile;
}
}
break;
}
renderBackground(back);
renderTiles(tile, layout);
}
kmahjongg'Preview::paintEvent() (./kdegames/kmahjongg/Preview.cpp:377)
void Preview::paintEvent( QPaintEvent* ){
drawFrame->repaint(false);
}
kmahjongg'Preview::parseFile() (./kdegames/kmahjongg/Preview.cpp:382)
void Preview::parseFile(const char *in, QString &out) {
QString tmp;
QString prefix;
prefix=locate("appdata", "pics/default.tileset");
QFileInfo f(prefix);
prefix=f.dirPath();
// remove any trailing \n
for (const char *p=in; *p; p++)
if (*p == ':') {
tmp += prefix;
tmp += "/";
} else {
if (*p != '\n')
tmp += *p;
}
out = tmp;
}
// the user selected ok, or apply. This method passes the changes
// across to the game widget and if necessary forces a board redraw
// (unnecessary on layout changes since it only effects the next game)
kmahjongg'Preview::applyChange() (./kdegames/kmahjongg/Preview.cpp:411)
void Preview::applyChange(void) {
switch (previewType) {
case background:
loadBackground(selectedFile, false);
break;
case tileset:
loadTileset(selectedFile);
break;
case board:
loadBoard(selectedFile);
break;
case theme:
if (themeLayout != "" && themeBack != "" && themeTileset !="") {
loadBackground(themeBack, false);
loadTileset(themeTileset);
loadBoard(themeLayout);
}
break;
}
// don't redraw for a layout change
if (previewType == board || previewType == theme) {
layoutChange();
} else {
boardRedraw(true);
}
// either way we mark the current value as unchanged
markUnchanged();
}
// Render the background to the pixmap.
kmahjongg'Preview::renderBackground() (./kdegames/kmahjongg/Preview.cpp:449)
void Preview::renderBackground(const char *bg) {
QImage img;
QImage tmp;
QPixmap *p;
QPixmap *b;
p = drawFrame->getPreviewPixmap();
back.load(bg, p->width(), p->height());
b = back.getBackground();
bitBlt( p, 0,0,
b,0,0, b->width(), b->height(), CopyROP );
}
// This method draws a mini-tiled board with no tiles missing.
kmahjongg'Preview::renderTiles() (./kdegames/kmahjongg/Preview.cpp:465)
void Preview::renderTiles(const char *file, const char *layout) {
tiles.loadTileset(file, true);
boardLayout.loadBoardLayout(layout);
QPixmap *dest = drawFrame->getPreviewPixmap();
int xOffset = tiles.width()/2;
int yOffset = tiles.height()/2;
short tile = 0;
// we iterate over the depth stacking order. Each sucessive level is
// drawn one indent up and to the right. The indent is the width
// of the 3d relief on the tile left (tile shadow width)
for (int z=0; z<BoardLayout::depth; z++) {
// we draw down the board so the tile below over rights our border
for (int y = 0; y < BoardLayout::height; y++) {
// drawing right to left to prevent border overwrite
for (int x=BoardLayout::width-1; x>=0; x--) {
int sx = x*(tiles.qWidth() )+xOffset;
int sy = y*(tiles.qHeight() )+yOffset;
if (boardLayout.getBoardData(z, y, x) != '1') {
continue;
}
QPixmap *t = tiles.unselectedPixmaps(tile);
// Only one compilcation. Since we render top to bottom , left
// to right situations arise where...:
// there exists a tile one q height above and to the left
// in this situation we would draw our top left border over it
// we simply split the tile draw so the top half is drawn
// minus border
if ((x>1) && (y>0) && boardLayout.getBoardData(z,y-1,x-2)=='1'){
bitBlt( dest, sx+2, sy,
t, 2,0, t->width(), t->height()/2, CopyROP );
bitBlt( dest, sx, sy+t->height()/2,
t, 0,t->height()/2,t->width(),t->height()/2,CopyROP);
} else {
bitBlt( dest, sx, sy,
t, 0,0, t->width(), t->height(), CopyROP );
}
tile++;
if (tile == 35)
tile++;
tile = tile % 43;
}
}
xOffset +=tiles.shadowSize();
yOffset -=tiles.shadowSize();
}
}
// this really does not belong here. It will be fixed in v1.1 onwards
kmahjongg'Preview::saveTheme() (./kdegames/kmahjongg/Preview.cpp:520)
void Preview::saveTheme(void) {
QString back = preferences.background();
QString tile = preferences.tileset();
QString layout = preferences.layout();
QString with = ":";
// we want to replace any path in the default store
// with a +
QRegExp p(locate("data_dir", "/kmahjongg/pics/"));
back.replace(p,with);
tile.replace(p,with);
layout.replace(p,with);
// Get the name of the file to save
KURL url = KFileDialog::getSaveURL(
NULL,
"*.theme",
this,
i18n("Save theme." ));
if ( url.isEmpty() )
return;
if( !url.isLocalFile() )
{
KMessageBox::sorry( 0L, i18n( "Only saving to local files currently supported." ) );
return;
}
// Are we over writing an existin file, or was a directory selected?
QFileInfo f( url.path() );
if( f.isDir() )
return;
if (f.exists()) {
// if it already exists, querie the user for replacement
int res=KMessageBox::warningYesNo(this,
i18n("A file with that name "
"already exists, do you "
"wish to overwrite it?"));
if (res != KMessageBox::Yes)
return ;
}
FILE *outFile = fopen( url.path(), "w" );
if (outFile == NULL) {
KMessageBox::sorry(this,
i18n("Could not write to file. Aborting."));
return;
}
fprintf(outFile,"%s\n%s\n%s\n%s\n",
themeMagicV1_0,
(const char *) tile,
(const char *) back,
(const char *) layout);
fclose(outFile);
}