From 84da08d7b7fcda12c85caeb5a10b4903770a6f69 Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeaddons@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- atlantikdesigner/Makefile.am | 17 + atlantikdesigner/TODO | 15 + atlantikdesigner/atlantikdesigner.desktop | 170 +++ atlantikdesigner/atlantikdesignerui.rc | 24 + atlantikdesigner/configure.in.bot | 9 + atlantikdesigner/configure.in.in | 7 + atlantikdesigner/designer/Makefile.am | 10 + atlantikdesigner/designer/boardinfo.cpp | 186 ++++ atlantikdesigner/designer/boardinfo.h | 74 ++ atlantikdesigner/designer/designer.cpp | 1099 ++++++++++++++++++++ atlantikdesigner/designer/designer.h | 106 ++ atlantikdesigner/designer/editor.cpp | 938 +++++++++++++++++ atlantikdesigner/designer/editor.h | 310 ++++++ atlantikdesigner/designer/group.cpp | 242 +++++ atlantikdesigner/designer/group.h | 99 ++ atlantikdesigner/designer/main.cpp | 37 + atlantikdesigner/pics/Makefile.am | 1 + .../pics/hi16-app-atlantikdesigner.png | Bin 0 -> 785 bytes .../pics/hi32-app-atlantikdesigner.png | Bin 0 -> 1640 bytes 19 files changed, 3344 insertions(+) create mode 100644 atlantikdesigner/Makefile.am create mode 100644 atlantikdesigner/TODO create mode 100644 atlantikdesigner/atlantikdesigner.desktop create mode 100644 atlantikdesigner/atlantikdesignerui.rc create mode 100644 atlantikdesigner/configure.in.bot create mode 100644 atlantikdesigner/configure.in.in create mode 100644 atlantikdesigner/designer/Makefile.am create mode 100644 atlantikdesigner/designer/boardinfo.cpp create mode 100644 atlantikdesigner/designer/boardinfo.h create mode 100644 atlantikdesigner/designer/designer.cpp create mode 100644 atlantikdesigner/designer/designer.h create mode 100644 atlantikdesigner/designer/editor.cpp create mode 100644 atlantikdesigner/designer/editor.h create mode 100644 atlantikdesigner/designer/group.cpp create mode 100644 atlantikdesigner/designer/group.h create mode 100644 atlantikdesigner/designer/main.cpp create mode 100644 atlantikdesigner/pics/Makefile.am create mode 100644 atlantikdesigner/pics/hi16-app-atlantikdesigner.png create mode 100644 atlantikdesigner/pics/hi32-app-atlantikdesigner.png (limited to 'atlantikdesigner') diff --git a/atlantikdesigner/Makefile.am b/atlantikdesigner/Makefile.am new file mode 100644 index 0000000..1c6ba3d --- /dev/null +++ b/atlantikdesigner/Makefile.am @@ -0,0 +1,17 @@ +INCLUDES = $(all_includes) +LDFLAGS = $(all_libraries) $(KDE_RPATH) +LDADD = $(LIB_KSYCOCA) $(LIB_KFILE) + +SUBDIRS = designer pics + +EXTRA_DIST = atlantikdesigner.desktop + +xdg_apps_DATA = atlantikdesigner.desktop + +METASOURCES = AUTO + +rcdir = $(kde_datadir)/atlantikdesigner +rc_DATA = atlantikdesignerui.rc + +messages: rc.cpp + $(XGETTEXT) `find . -name '*.cpp'` -o $(podir)/atlantikdesigner.pot diff --git a/atlantikdesigner/TODO b/atlantikdesigner/TODO new file mode 100644 index 0000000..3450d34 --- /dev/null +++ b/atlantikdesigner/TODO @@ -0,0 +1,15 @@ +Bugfixes +-------- + +- fix leak of 4-300 Kb each time one switches board, i've investigated + but haven't found leak :( +- let you delete last card in a stack, it made designer crash, so delete + doesn't do anything if there is only 1 card on stack +- disable "Less properties" when there are no properties for a card + +For 0.3.0 +--------- + +- support 's go= instead of type=go in +- libatlantikui exists, make designer a seperate app again +- remove type= entirely (depends on proper monopd groups) diff --git a/atlantikdesigner/atlantikdesigner.desktop b/atlantikdesigner/atlantikdesigner.desktop new file mode 100644 index 0000000..7b883a9 --- /dev/null +++ b/atlantikdesigner/atlantikdesigner.desktop @@ -0,0 +1,170 @@ +[Desktop Entry] +Type=Application +Exec=atlantikdesigner -caption "%c" %i %m +Icon=atlantikdesigner +Terminal=false +Name=Atlantik Designer +Name[af]=Atlantik Ontwerper +Name[ar]=المصمم Atlantik +Name[az]=Atlantik Tərtib Edicisi +Name[bg]=Дизайнер на Atlantik +Name[br]=Ergrafer Atlantik +Name[ca]=Dissenyador Atlantik +Name[cs]=Atlantik designer +Name[cy]=Dylunydd Atlantik +Name[da]=Atlantik-designer +Name[de]=Atlantik Spielbrett-Editor +Name[el]=Σχεδιαστής Atlantik +Name[eo]=Atlantika Desegnilo +Name[es]=Diseñador de Atlantik +Name[et]=Atlantik disainer +Name[fa]=طراح Atlantik +Name[fo]=Atlantik-sniðari +Name[fy]=Atlantik Untwerper +Name[gl]=Deseñador Atlantik +Name[he]=מעצב Atlantik +Name[hi]=अटलांटिक डिज़ाइनर +Name[hr]=Atlantik Dizajner +Name[ja]=Atlantik デザイナー +Name[ka]=Atlantik დიზაინერი +Name[kk]=Atlantik конструкторы +Name[km]=កម្មវិធី​រចនា Atlantik​ +Name[lv]=Atlantijas Konstruktors +Name[mk]=Атлантик дизајнер +Name[mt]=Diżinjatur Atlantik +Name[nb]=Atlantik-designer +Name[nds]=Atlantik-Maker +Name[ne]=एटालन्टिक डिजाइनर +Name[nso]=Mokgabisi wa Atlantik +Name[pa]=ਐਟਲਾਟਿਕ ਨਿਰਮਾਤਾ +Name[pl]=Projektant do programu Atlantyk +Name[ru]=Редактор полей Atlantik +Name[sl]=Snovalnik za Atlantik +Name[sr]=Atlantik-ов дизајнер +Name[sr@Latn]=Atlantik-ov dizajner +Name[sv]=Atlantik designer +Name[ta]=அட்லாண்டிக் வடிவமைப்பான் +Name[tg]=Коркарди Atlantik +Name[th]=ออกแบบเกมแอตแลนติก +Name[tr]=Atlantik Tasarımcısı +Name[uk]=Редактор Atlantik +Name[uz]=Atlantik dizayneri +Name[uz@cyrillic]=Atlantik дизайнери +Name[vi]=Bộ thiết kế Atlantik +Name[xh]=Umzobi we Atlantik +Name[zh_CN]=Atlantik 设计器 +Name[zh_TW]=Atlantik 設計者 +Comment=Game board designer for Atlantik +Comment[af]=Speletjie bord ontwerper vir Atlantik +Comment[ar]=مصمم لوحات ألعاب لـ Atlantic +Comment[az]=Atlantik üçün oyun lövhəsi tərtib edicisi +Comment[bg]=Дизайнер на игралната дъска за играта Atlantik +Comment[bs]=Dizajner tabli za igru za Atlantik +Comment[ca]=Dissenyador de jocs de taula per a Atlantik +Comment[cs]=Návrhář hracích desek pro hru Atlantik +Comment[cy]=Dylunydd byrddau gêm am Atlantik +Comment[da]=Spillebræt-designer for Atlantik +Comment[de]=Spielbrett-Editor für das Spiel "Atlantik" +Comment[el]=Σχεδιαστής πινάκων παιχνιδιού για το Atlantik +Comment[eo]=Breta desegnilo por Atlantiko +Comment[es]=Diseñador de tableros de juego para Atlantik +Comment[et]=Atlantik mängulaua disainer +Comment[eu]=Atlantik jokorako taula diseinatzeko tresna +Comment[fa]=طراح تخته بازی برای Atlantik +Comment[fi]=Pelilaudan suunnitteluohjelma Atlantikiin +Comment[fo]=Spælabrettissniðari til Atlantik +Comment[fr]=Concepteur de plateaux de jeu pour Atlantik +Comment[fy]=Spulboerdûntwerper foar Atlantik +Comment[ga]=Dearthóir clár cluiche le haghaidh Atlantik +Comment[gl]=O deseñador de taboleiro de Atlantik +Comment[he]=מעצב לוחות משחק ל־Atlantik +Comment[hi]=अटलांटिक के लिए खेल बिसातडिज़ाइनर +Comment[hr]=Dizajner ploče za Atlantik +Comment[hu]=Táblatervező az Atlantikhoz +Comment[is]=Hönnun borða fyrir Atlantik +Comment[it]=Per progettare tabelloni per Atlantik +Comment[ja]=Atlantik 用のゲームボードデザイナー +Comment[ka]=Atlantik-სთვის სათამაშო დაფის დიზაინერი +Comment[kk]=Atlantik ойын тақта конструкторы +Comment[km]=កម្មវិធី​រចនា​ក្ដារ​ល្បែង​សម្រាប់ Atlantik +Comment[lt]=Žaidimo stalo dizaineris, skirtas Atlantik +Comment[lv]=Spēļu galda konstruktors Antlantikai +Comment[mk]=Дизајнер за игри на табла за Атлантик +Comment[ms]=Pereka permainan papan untuk Atlantik +Comment[mt]=Diżinjatur ta' logħob tal-bord għall-Atlantik +Comment[nb]=Spillebrettbygger for Atlantik +Comment[nds]=En Speelbrettmaker för Atlantik +Comment[ne]=एटलान्टिकका लागि खेल पाटी डिजाइनर +Comment[nl]=Spelbordontwerper voor Atlantik +Comment[nn]=Utforming av spelebrett for Atlantik +Comment[pl]=Program do projektowania plansz dla programu Atlantyk +Comment[pt]=O desenhador do tabuleiro do Atlantik +Comment[pt_BR]=O designer de jogo para o Atlantik +Comment[ro]=Desenator de table de joc pentru Atlantik +Comment[ru]=Редактор полей Atlantik +Comment[sk]=Návrhár pre hru Atlantik +Comment[sl]=Snovalnik igralnih miz za Atlantik +Comment[sr]=Дизајнер табли за игру Atlantik +Comment[sr@Latn]=Dizajner tabli za igru Atlantik +Comment[sv]=Atlantik spelplanskonstruktion +Comment[ta]=அட்லாண்டிக்கிற்கான மேஜை விளையாட்டு வடிவமைப்பாளர் +Comment[tg]=Коркарди дизайн барои бозии Atlantik +Comment[th]=เครื่องมือออกแบบกระดานเกมแอตแลนติก +Comment[tr]=Atlantik için oyun tahtası düzenleyici +Comment[uk]=Редактор гри Atlantik +Comment[uz]=Atlantik uchun oʻyin maydoni tahrirchisi +Comment[uz@cyrillic]=Atlantik учун ўйин майдони таҳрирчиси +Comment[vi]=Bộ thiết kế bảng trò chơi cho Atlantik +Comment[xh]=Umzobi womdlalo webhodi we Atlantik +Comment[zh_CN]=Atlantik 的游戏盘设计器 +Comment[zh_TW]=Atlantik 遊戲板設計師 +Categories=Qt;KDE;Game;BoardGame; +GenericName=Monopoly®-like Board Designer +GenericName[bg]=Дизайнер на Atlantik +GenericName[ca]=Dissenyador de taulells de tipus Monopoly® +GenericName[cs]=Návrhář desky podobný Monopolům® +GenericName[da]=Matador®-lignende brætdesigner +GenericName[de]=Monopoly®-ähnlicher Spielbrett-Editor +GenericName[el]=Σχεδιαστής πίνακα σε στυλ Monopoly® +GenericName[eo]=Monopoly-similaj breta desegnilo +GenericName[es]=Diseñador de tableros similar al Monopoly® +GenericName[et]=Monopoly® laadsete mängulaudade disainer +GenericName[eu]=Monopoly®-bezalako diseinatzailea +GenericName[fi]=Monopoly®-tyylisen pelin suunnitteluohjelma +GenericName[fr]=Concepteur de plateaux dans le style du Monopoly® +GenericName[fy]=Monopoly®-eftige boerdûntwerper +GenericName[ga]=Dearthóir Cluichí cosúil le Monopoly® +GenericName[gl]=Deseñador de Taboleiros tipo Monopoly® +GenericName[he]=בונה לוחות לתואמי מונופל® +GenericName[hr]=Dizajner ploče za igre poput Monopola® +GenericName[hu]=Monopoly®-szerű táblatervező +GenericName[is]=Matador (Monopoly) borðhönnuður +GenericName[it]=Gioco da tavolo simile a Monopoly® +GenericName[ja]=Monopoly® 風ボードゲームのデザイナー +GenericName[ka]=Monopoly®-ს მაგვარი სამაგიდო თამაში +GenericName[kk]=Monopoly® секілді тақта конструкторы +GenericName[km]=កម្មវិធី​រចនា​ក្ដារ Monopoly®-like +GenericName[lt]=Monopoly® primenančių lentų kūrimo priemonė +GenericName[mk]=Дизајнер за табли за игри како Монопол® +GenericName[nb]=Monopol®-aktig spillebrettmaker +GenericName[nds]=Maker för Monopoly®-liek Speelbreed +GenericName[ne]=एकाधिकारी®-जस्तै पाटी डिजाइनर +GenericName[nl]=Monopoly®-achtige bordontwerper +GenericName[nn]=Monopol®-liknande brettutforming +GenericName[pa]=Monopoly®-ਵਰਗੀ ਬੋਰਡ ਡਿਜ਼ਾਈਨਰ +GenericName[pl]=Edytor planszy do gry typu Monopoly® +GenericName[pt]=Desenhador de Tabuleiros tipo Monopoly® +GenericName[pt_BR]=Construtor de Tabuleiros para o Atlantik +GenericName[ru]=Редактор полей Atlantik +GenericName[sk]=Board Designer typu Monopoly® +GenericName[sl]=Snovalnik plošč, podobnim za Monopoly® +GenericName[sr]=Дизајнер табли налик на Monopoly® +GenericName[sr@Latn]=Dizajner tabli nalik na Monopoly® +GenericName[sv]=Konstruktion av Monopol®-liknande spelplaner +GenericName[tr]=Monopoly®-like Tahta Düzenleyici +GenericName[uk]=Monopoly®-подібний дизайнер дошки +GenericName[uz]=Monopoly® oʻyinga oʻxshagan oʻyin maydoni tahrirchisi +GenericName[uz@cyrillic]=Monopoly® ўйинга ўхшаган ўйин майдони таҳрирчиси +GenericName[vi]=Bộ thiết kế bảng kiểu Monopoly® +GenericName[zh_CN]=类似 Monopoly(R) 的棋盘设计器 +GenericName[zh_TW]=類似 Monopoly® 棋盤設計師 diff --git a/atlantikdesigner/atlantikdesignerui.rc b/atlantikdesigner/atlantikdesignerui.rc new file mode 100644 index 0000000..99d942e --- /dev/null +++ b/atlantikdesigner/atlantikdesignerui.rc @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/atlantikdesigner/configure.in.bot b/atlantikdesigner/configure.in.bot new file mode 100644 index 0000000..74e3848 --- /dev/null +++ b/atlantikdesigner/configure.in.bot @@ -0,0 +1,9 @@ +if test "x$ATLANTIKDESIGNER_SUBDIR" = "x"; then + echo "" + echo "You're missing the Atlantik header files, therefore Atlantik Designer" + echo "will not be compiled. Install Atlantik from kdegames if you want to" + echo "compile Atlantik Designer." + echo "" + all_tests=bad +fi + diff --git a/atlantikdesigner/configure.in.in b/atlantikdesigner/configure.in.in new file mode 100644 index 0000000..394e4f9 --- /dev/null +++ b/atlantikdesigner/configure.in.in @@ -0,0 +1,7 @@ +ATLANTIKDESIGNER_SUBDIR= +KDE_CHECK_HEADER(atlantik/ui/board.h, ATLANTIKDESIGNER_SUBDIR=atlantikdesigner) + +if test -z "$ATLANTIKDESIGNER_SUBDIR"; then + dnl dir will only be compiled conditionally + DO_NOT_COMPILE="$DO_NOT_COMPILE atlantikdesigner" +fi diff --git a/atlantikdesigner/designer/Makefile.am b/atlantikdesigner/designer/Makefile.am new file mode 100644 index 0000000..ca9fadc --- /dev/null +++ b/atlantikdesigner/designer/Makefile.am @@ -0,0 +1,10 @@ +bin_PROGRAMS = atlantikdesigner +INCLUDES = -I$(kde_includes)/atlantic $(all_includes) +AM_LDFLAGS = $(all_libraries) $(KDE_RPATH) +LDADD = -latlantikui -lkdegames $(LIB_KIO) + +SUBDIRS = + +atlantikdesigner_SOURCES = boardinfo.cpp designer.cpp editor.cpp main.cpp group.cpp + +METASOURCES = AUTO diff --git a/atlantikdesigner/designer/boardinfo.cpp b/atlantikdesigner/designer/boardinfo.cpp new file mode 100644 index 0000000..9bc6dbb --- /dev/null +++ b/atlantikdesigner/designer/boardinfo.cpp @@ -0,0 +1,186 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "boardinfo.h" + +BoardInfoDlg::BoardInfoDlg(bool editable, BoardInfo *info, QWidget *parent, const char *_name, bool modal) + : KDialogBase(KDialogBase::Tabbed, i18n("Gameboard Information"), (editable? Ok|Apply|Cancel : Close), (editable? Ok : Close), parent, _name, modal) +{ + if (!info) + return; + this->info = info; + + setWFlags(WDestructiveClose); + + QFrame *about = addPage(i18n("Information")); + QVBoxLayout *aboutLayout = new QVBoxLayout(about, spacingHint()); + + if (editable) + { + aboutLayout->addWidget(name = new KLineEdit(about)); + name->setText(info->name); + } + else + { + aboutLayout->addWidget(new QLabel(info->name, about)); + name = 0; + } + + QHBoxLayout *versionLayout = new QHBoxLayout(aboutLayout, spacingHint()); + versionLayout->addWidget(new QLabel(i18n("Version:"), about)); + if (editable) + { + versionLayout->addWidget(version = new KLineEdit(about)); + version->setText(info->version); + } + else + versionLayout->addWidget(new QLabel(info->version, about)); + + QHBoxLayout *urlLayout = new QHBoxLayout(aboutLayout, spacingHint()); + urlLayout->addWidget(new QLabel(i18n("URL:"), about)); + if (editable) + urlLayout->addWidget(url = new KLineEdit(info->url, about)); + else + urlLayout->addWidget(new KURLLabel(info->url, info->url, about)); + + aboutLayout->addStretch(3); + + aboutLayout->addWidget(new QLabel(i18n("Description:"), about)); + aboutLayout->addStretch(); + aboutLayout->addWidget(description = new KLineEdit(about)); + description->setText(info->description); + if (!editable) + { + description->setReadOnly(true); + } + + if (editable) + { + QHBoxLayout *bgLayout = new QHBoxLayout(aboutLayout, spacingHint()); + bgLayout->addWidget(new QLabel(i18n("Background color:"), about)); + bgColor = new KColorButton(info->bgColor, about); + bgLayout->addWidget(bgColor); + } + else + bgColor = 0; + + QFrame *authorsFrame = addPage(i18n("&Authors")); + QVBoxLayout *authorsLayout = new QVBoxLayout(authorsFrame, spacingHint()); + authorsLayout->addWidget(authors = new LotsaEdits(editable, info->authors, authorsFrame)); + + QFrame *creditsFrame = addPage(i18n("&Thanks To")); + QVBoxLayout *creditsLayout = new QVBoxLayout(creditsFrame, spacingHint()); + creditsLayout->addWidget(credits = new LotsaEdits(editable, info->credits, creditsFrame)); +} + +void BoardInfoDlg::slotApply() +{ + info->name = name->text(); + info->description = description->text(); + info->version = version->text(); + info->url = url->text(); + info->authors = authors->save(); + info->credits = credits->save(); + + if (bgColor) + info->bgColor = bgColor->color().name(); + + emit okClicked(); + KDialogBase::slotApply(); +} + +void BoardInfoDlg::slotOk() +{ + slotApply(); + + KDialogBase::slotOk(); +} + +/////////////////////////////////// + +LotsaEdits::LotsaEdits(bool editable, QStringList defaults, QWidget *parent, const char *name) : QWidget(parent, name) +{ + list.setAutoDelete(true); + this->editable = editable; + + layout = new QVBoxLayout(this, KDialogBase::spacingHint()); + QHBoxLayout *hlayout = new QHBoxLayout(layout, KDialogBase::spacingHint()); + + if (editable) + { + KPushButton *more = new KPushButton(i18n("&Add Name"), this); + hlayout->addWidget(more); + connect(more, SIGNAL(clicked()), this, SLOT(more())); + hlayout->addStretch(); + KPushButton *less= new KPushButton(i18n("&Delete Name"), this); + hlayout->addWidget(less); + connect(less, SIGNAL(clicked()), this, SLOT(less())); + } + + layout->addStretch(); + + for (QStringList::Iterator it = defaults.begin(); it != defaults.end(); ++it) + { + more(); + if (editable) + static_cast(list.last())->setText(*it); + else + static_cast(list.last())->setText(*it); + } +} + +void LotsaEdits::more() +{ + QWidget *edit; + if (editable) + edit = new KLineEdit(this); + else + edit = new QLabel(this); + layout->addWidget(edit); + list.append(edit); + edit->show(); +} + +void LotsaEdits::less() +{ + list.removeLast(); + /* + QWidget *edit = 0; + for (edit = list.first(); edit; edit = list.next()) + { + if (edit->hasFocus()) + { + list.remove(); + break; + } + } + */ +} + +QStringList LotsaEdits::save() +{ + QStringList ret; + + QWidget *edit = 0; + for (edit = list.first(); edit; edit = list.next()) + if (editable) + ret.append(static_cast(edit)->text()); + else + ret.append(static_cast(edit)->text()); + + return ret; +} + +#include "boardinfo.moc" diff --git a/atlantikdesigner/designer/boardinfo.h b/atlantikdesigner/designer/boardinfo.h new file mode 100644 index 0000000..00825a5 --- /dev/null +++ b/atlantikdesigner/designer/boardinfo.h @@ -0,0 +1,74 @@ +#ifndef ATLANTIK_BOARDINFO_H +#define ATLANTIK_BOARDINFO_H + +#include +#include +#include +#include +#include + +#include + +class KColorButton; +class KLineEdit; +class KURLLabel; + +class QVBoxLayout; + +struct BoardInfo +{ + BoardInfo() { bgColor = Qt::lightGray; } + QString name; + QStringList authors; + QStringList credits; + QString description; + QString url; + QString version; + QColor bgColor; +}; + +class LotsaEdits : public QWidget +{ + Q_OBJECT + + public: + LotsaEdits(bool, QStringList=QStringList(), QWidget *parent=0, const char *name=0); + + public slots: + QStringList save(); + + private slots: + void more(); + void less(); + + private: + bool editable; + QPtrList list; + QVBoxLayout *layout; +}; + +class BoardInfoDlg : public KDialogBase +{ + Q_OBJECT + + public: + BoardInfoDlg(bool editable, BoardInfo *, QWidget *parent=0, const char *_name=0, bool = true); + + protected slots: + void slotOk(); + void slotApply(); + + private: + KLineEdit *name; + KLineEdit *url; + KLineEdit *version; + KLineEdit *description; + KColorButton *bgColor; + + LotsaEdits *authors; + LotsaEdits *credits; + + BoardInfo *info; +}; + +#endif diff --git a/atlantikdesigner/designer/designer.cpp b/atlantikdesigner/designer/designer.cpp new file mode 100644 index 0000000..11da0e3 --- /dev/null +++ b/atlantikdesigner/designer/designer.cpp @@ -0,0 +1,1099 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "boardinfo.h" +#include "editor.h" +#include "designer.h" + +AtlanticDesigner::AtlanticDesigner(QWidget *parent, const char *name) + : KMainWindow(parent, name) +{ + firstBoard = true; + estates.setAutoDelete(true); + + isMod = false; + m_player = 0; + copiedEstate = 0; + editor = 0; + board = 0; + layout = 0; + + (void) KStdAction::quit(this, SLOT(close()), actionCollection()); + (void) KStdAction::open(this, SLOT(open()), actionCollection()); + (void) KStdAction::openNew(this, SLOT(openNew()), actionCollection()); + (void) KStdAction::save(this, SLOT(save()), actionCollection()); + (void) KStdAction::saveAs(this, SLOT(saveAs()), actionCollection()); + (void) new KAction(i18n("&Edit Gameboard Info..."), CTRL+Key_I, this, SLOT(info()), actionCollection(), "boardinfo"); + (void) new KAction(i18n("&Edit Groups..."), CTRL+Key_G, this, SLOT(editGroups()), actionCollection(), "groupeditor"); + + (void) new KAction(i18n("&Add 4 Squares"), "viewmag+", 0, this, SLOT(larger()), actionCollection(), "larger"); + (void) new KAction(i18n("&Remove 4 Squares"), "viewmag-", 0, this, SLOT(smaller()), actionCollection(), "smaller"); + (void) KStdAction::copy(this, SLOT(copy()), actionCollection()); + (void) KStdAction::paste(this, SLOT(paste()), actionCollection()); + (void) new KAction(i18n("&Up"), Key_Up, this, SLOT(up()), actionCollection(), "up"); + (void) new KAction(i18n("&Down"), Key_Down, this, SLOT(down()), actionCollection(), "down"); + (void) new KAction(i18n("&Left"), Key_Left, this, SLOT(left()), actionCollection(), "left"); + (void) new KAction(i18n("&Right"), Key_Right, this, SLOT(right()), actionCollection(), "right"); + + recentAct = KStdAction::openRecent(0, 0, actionCollection()); + connect(recentAct, SIGNAL(urlSelected(const KURL &)), this, SLOT(openRecent(const KURL &))); + recentAct->loadEntries(KGlobal::config(), "Designer recent files"); + + estateAct = new KListAction(i18n("Change Estate"), 0, 0, 0, actionCollection(), "estate_num"); + connect(estateAct, SIGNAL(activated(int)), SLOT(changeEstate(int))); + + createGUI("atlantikdesignerui.rc"); + + KConfig *config = kapp->config(); + config->setGroup("General"); + QColor defaultColor = colorGroup().background(); + defaultBg = config->readColorEntry("alternateBackground", &defaultColor); + config->setGroup("WM"); + defaultColor = colorGroup().dark(); + defaultFg = config->readColorEntry("activeBackground", &defaultColor); + + // these must match up to the ones in editor.cpp! + // I don't think these are used anymore. + types.append("street"); + types.append("cards"); + types.append("freeparking"); + types.append("tojail"); + types.append("tax"); + types.append("jail"); + + openNew(); + + resize(350, 400); + applyMainWindowSettings(KGlobal::config(), "DesignerTopLevelWindow"); +} + +AtlanticDesigner::~AtlanticDesigner() +{ + delete m_player; +} + +void AtlanticDesigner::initMembers() +{ + estates.clear(); + cards.clear(); + groups.clear(); + + boardInfo = BoardInfo(); + + for (ConfigEstateGroupList::Iterator it = groups.begin(); it != groups.end(); ++it) + if ((*it).name() == "Default") + return; + + ConfigEstateGroup defaultGroup("Default"); + defaultGroup.setBgColor(defaultBg); + defaultGroup.setFgColor(defaultFg); + groups.append(defaultGroup); +} + +void AtlanticDesigner::initBoard() +{ + // let her say her prayers (if she's alive) + if (!firstBoard) + editor->aboutToDie(); + + firstBoard = false; + + delete editor; + delete board; + delete layout; + + board = new AtlantikBoard(0, max, AtlantikBoard::Edit, this, "Board"); + + setCentralWidget(board); + layout = new QVBoxLayout(board->centerWidget()); + editor = new EstateEdit(&groups, &estates, &cards, board->centerWidget(), "Estate Editor"); + connect(editor, SIGNAL(goChecked(int)), this, SLOT(goChanged(int))); + connect(editor, SIGNAL(updateBackground()), this, SLOT(updateBackground())); + connect(editor, SIGNAL(resized()), board, SLOT(slotResizeAftermath())); + layout->addWidget(editor); + + editor->setReady(false); + + board->show(); + editor->show(); + + initToken(); +} + +void AtlanticDesigner::initToken() +{ + if (!m_player) + m_player = new Player(0); + else + m_player->setLocation(0); + + board->addToken(m_player); + + connect(m_player, SIGNAL(changed(Player *)), board, SLOT(playerChanged(Player *))); +} + +void AtlanticDesigner::openNew() +{ + if (warnClose()) + return; + filename = QString::null; + + max = 40; + + initMembers(); + initBoard(); + + for (int i = 0; i < 40; ++i) + { + (void) newEstate(i); + } + + doCaption(false); + updateJumpMenu(); + + groupsChanged(); + updateBackground(); + + QTimer::singleShot(500, this, SLOT(setPlayerAtBeginning())); + doCaption(false); +} + +ConfigEstate *AtlanticDesigner::newEstate(int i) +{ + ConfigEstate *estate = new ConfigEstate(i); + estate->setName(i18n("New Estate")); + estate->setPrice(100); + for (int j = 0; j < 6; ++j) + estate->setRent(j, 10 * (j + 1)); + estate->setChanged(false); + estates.insert(i, estate); + + connect(estate, SIGNAL(LMBClicked(Estate *)), this, SLOT(changeEstate(Estate *))); + connect(estate, SIGNAL(changed()), this, SLOT(modified())); + + board->addEstateView(estate); + + return estate; +} + +bool AtlanticDesigner::warnClose() +{ + if (isMod) + { + int result = KMessageBox::warningYesNoCancel(this, i18n("There are unsaved changes to gameboard. Save them?"), i18n("Unsaved Changes"), KStdGuiItem::save(), KStdGuiItem::discard(), "DiscardAsk", true); + switch(result) + { + case KMessageBox::Yes: + save(); + // fallthrough + case KMessageBox::No: + return false; + case KMessageBox::Cancel: + return true; + } + } + return false; +} + +void AtlanticDesigner::open() +{ + if (warnClose()) + return; + + filename = KFileDialog::getOpenFileName(); + + if (filename.isNull()) + return; + + openFile(filename); + recentAct->addURL(KURL::fromPathOrURL( filename )); +} + +void AtlanticDesigner::openRecent(const KURL &url) +{ + if (url.isLocalFile()) + { + filename = url.path(); + openFile(filename); + + recentAct->popupMenu()->setItemChecked(recentAct->currentItem(), false); + } + else + { + recentAct->removeURL(url); + } +} + +void AtlanticDesigner::openFile(const QString &filename) +{ + enum ParseMode { Parse_Nothing, Parse_General, Parse_Board, Parse_Cards, Parse_EstateGroups, Parse_Estates }; + QFile f(filename); + if (!f.open(IO_ReadOnly)) + return; + + initMembers(); + + QTextStream t(&f); + t.setCodec(QTextCodec::codecForName("utf8")); + + QString s = t.readLine(); + int parseMode = Parse_Nothing; + + CardStack *curCardStack = 0; + + int goEstate = 0; + int i; + for (i = 0; !t.atEnd();) + { + s = s.stripWhiteSpace(); + + if (s.isEmpty()) + { + s = t.readLine(); + continue; + } + + QString name; + + if (s.left(1) == "<") + { + if (s == "") + parseMode = Parse_General; + else if (s == "") + parseMode = Parse_Board; + else if (s == "") + parseMode = Parse_EstateGroups; + else if (s == "") + parseMode = Parse_Cards; + else if (s == "") + parseMode = Parse_Estates; + + s = t.readLine(); + continue; + } + + // this for outside-of-[]-settings + int eqSign = s.find("="); + if (eqSign >= 0) + { + QString key = s.left(eqSign); + QString value = s.right(s.length() - eqSign - 1); + + if (parseMode == Parse_Cards) + { + if (key == "groupname") + { + cards.append(CardStack(value)); + curCardStack = &cards.last(); + } + } + else if (parseMode == Parse_General) + { + if (key == "name") + boardInfo.name = value; + else if (key == "description") + boardInfo.description = value; + else if (key == "version") + boardInfo.version = value; + else if (key == "url") + boardInfo.url = value; + else if (key == "authors") + boardInfo.authors = QStringList::split(",", value); + else if (key == "credits") + boardInfo.credits = QStringList::split(",", value); + } + else if (parseMode == Parse_Board) + { + if (key == "go") + goEstate = value.toInt(); + else if (key == "bgcolor") + boardInfo.bgColor.setNamedColor(value); + } + + s = t.readLine(); + continue; + } + + name = s.left(s.find("]")); + name = name.right(name.length() - name.find("[") - 1); + + if (name.isEmpty()) + name = i18n("No Name"); + + // for estates + int type = FreeParking; + QString group, takeCard; + int price = -1; + int rent[6] = {-1, -1, -1, -1, -1, -1}; + int tax = -1; + int taxPercentage = -1; + int passMoney = -1; + QColor forceBg; + + // for groups + QColor color, bgColor; + QString rentMath; + int housePrice = -1; + int globalPrice = -1; + + // for cards + QStringList keys; + QValueList values; + + while (true) + { + if (t.atEnd()) + break; + + s = t.readLine().stripWhiteSpace(); + + if (s.left(1) == "[" || s.left(1) == "<") + break; + + int eqSign = s.find("="); + if (eqSign < 0) + continue; + + QString key = s.left(eqSign); + QString value = s.right(s.length() - eqSign - 1); + + //////////////////////////////// ESTATES + if (parseMode == Parse_Estates) + { + if (key == "price") + price = value.toInt(); + else if (key.left(4) == "rent") + { + int houses = key.right(1).toInt(); + if (houses < 0 || houses > 5) + continue; + + rent[houses] = value.toInt(); + } + else if (key == "tax") + { + tax = value.toInt(); + type = Tax; + } + else if (key == "taxpercentage") + taxPercentage = value.toInt(); + else if (key == "group") + { + group = value; + type = Street; + } + else if (key == "tojail") + type = ToJail; + else if (key == "jail") + type = Jail; + else if (key == "freeparking") + type = FreeParking; + else if (key == "takecard") + { + takeCard = value; + type = Cards; + } + else if (key == "bgcolor") + forceBg = QColor(value); + else if (key == "passmoney") + passMoney = value.toInt(); + } + else if (parseMode == Parse_EstateGroups) + { + if (key == "color") + color.setNamedColor(value); + else if (key == "bgcolor") + bgColor.setNamedColor(value); + else if (key == "houseprice") + housePrice = value.toInt(); + else if (key == "price") + globalPrice = value.toInt(); + else if (key == "rentmath") + rentMath = value; + } + else if (parseMode == Parse_Cards) + { + bool ok; + int v = value.toInt(&ok); + if (!ok) + continue; + + if (key == "pay" && v < 0) + { + v *= -1; + key = "collect"; + } + else if (key == "payeach" && v < 0) + { + v *= -1; + key = "collecteach"; + } + else if (key == "advance" && v < 0) + { + v *= -1; + key = "goback"; + } + + keys.append(key); + values.append(v); + } + } + + if (parseMode == Parse_Estates) + { + ConfigEstate *estate = new ConfigEstate(i); + estate->setName(name); + estate->setType(type); + if (!group.isEmpty()) + estate->setGroup(group); + estate->setTakeCard(takeCard); + estate->setPrice(price); + for (int j = 0; j < 6; j++) + estate->setRent(j, rent[j]); + estate->setTax(tax); + estate->setTaxPercentage(taxPercentage); + estate->setForceBg(forceBg); + estate->setPassMoney(passMoney); + estates.append(estate); + + connect(estate, SIGNAL(LMBClicked(Estate *)), this, SLOT(changeEstate(Estate *))); + connect(estate, SIGNAL(changed()), this, SLOT(modified())); + i++; + } + else if (parseMode == Parse_Cards) + { + Card card; + card.name = name; + card.keys = keys; + card.values = values; + if (curCardStack) + curCardStack->append(card); + } + else if (parseMode == Parse_EstateGroups) + { + bool found = false; + for (ConfigEstateGroupList::Iterator it = groups.begin(); it != groups.end(); ++it) + { + if ((*it).name() == name) + { + found = true; + break; + } + } + + if (found) + continue; + + ConfigEstateGroup group(name); + group.setHousePrice(housePrice); + group.setGlobalPrice(globalPrice); + group.setFgColor(color); + group.setBgColor(bgColor); + group.setRentMath(rentMath); + groups.append(group); + } + } + + if (i < 8) + { + KMessageBox::detailedSorry(this, i18n("This board file is invalid; cannot open."), i18n("There are only %1 estates specified in this file.").arg(i)); + if (this->filename.isNull()) + close(); + return; + } + max = i; + + initBoard(); + ConfigEstate *estate = 0; + for (estate = estates.first(); estate; estate = estates.next()) + board->addEstateView(estate); + + if (goEstate >= 0 && goEstate < max - 1) + estates.at(goEstate)->setGo(true); + + groupsChanged(); + updateBackground(); + updateJumpMenu(); + + QTimer::singleShot(500, this, SLOT(setPlayerAtBeginning())); + doCaption(false); +} + +void AtlanticDesigner::updateJumpMenu() +{ + QStringList estates; + for (int i = 1; i <= max; i++) + estates.append(i18n("Jump to Estate %1").arg(QString::number(i))); + estateAct->setItems(estates); +} + +void AtlanticDesigner::setPlayerAtBeginning() +{ + ConfigEstate *go = 0; + for (go = estates.first(); go; go = estates.next()) + if (go->go()) + break; + + if (!go) + go = estates.first(); + + movePlayer(go); + editor->setEstate(go); +} + +void AtlanticDesigner::saveAs() +{ + QString oldfilename = filename; + filename = QString::null; + + save(); + + if (filename.isNull()) + { + filename = oldfilename; + return; + } + else + recentAct->addURL(KURL::fromPathOrURL( filename )); +} + +void AtlanticDesigner::save() +{ + (void) editor->saveEstate(); + QString oldfilename = filename; + if (filename.isNull()) + filename = KFileDialog::getOpenFileName(); + + if (filename.isNull()) + { + filename = oldfilename; + return; + } + + QFile f(filename); + if (!f.open(IO_WriteOnly)) + return; + + QTextStream t(&f); + t.setCodec(QTextCodec::codecForName("utf8")); + + t << "" << endl << endl; + if (!boardInfo.name.isEmpty()) + t << "name=" << boardInfo.name << endl; + if (!boardInfo.description.isEmpty()) + t << "description=" << boardInfo.description << endl; + if (!boardInfo.url.isEmpty()) + t << "url=" << boardInfo.url << endl; + if (!boardInfo.version.isEmpty()) + t << "version=" << boardInfo.version << endl; + if (!boardInfo.authors.isEmpty()) + t << "authors=" << boardInfo.authors.join(",") << endl; + if (!boardInfo.credits.isEmpty()) + t << "credits=" << boardInfo.credits.join(",") << endl; + + // FIXME: make configurable. Hardcoded defaults are still better than + // non-existant entries that would make the saved configs useless. + t << "minplayers=2" << endl; + t << "maxplayers=6" << endl; + t << "houses=32" << endl; + t << "hotels=16" << endl; + t << "startmoney=1500" << endl; + + t << endl; + t << "" << endl << endl; + + ConfigEstate *estate = 0; + bool hasGo = false; + for (estate = estates.first(); estate; estate = estates.next()) + { + if (estate->go()) + { + t << "go=" << estate->id() << endl; + hasGo = true; + break; + } + } + if (!hasGo) + t << "go=" << 0 << endl; + + if (boardInfo.bgColor.isValid()) + t << "bgcolor=" << boardInfo.bgColor.name() << endl; + + t << endl << endl; + + t << "" << endl; + + // double-prevent duplicates + QStringList writtenGroups; + + for (ConfigEstateGroupList::Iterator it = groups.begin(); it != groups.end(); ++it) + { + if (writtenGroups.contains((*it).name()) > 0) + continue; + + if ((*it).name() == "Default") + { + bool containsDefault = false; + for (estate = estates.first(); estate; estate = estates.next()) + { + if (estate->group() == "Default") + { + containsDefault = true; + break; + } + } + + if (!containsDefault) + continue; + } + + writtenGroups.append((*it).name()); + + t << endl << QString("[%1]").arg((*it).name()) << endl; + + if ((*it).globalPrice() > 0) + t << "price=" << (*it).globalPrice() << endl; + + if ((*it).fgColor().isValid()) + t << "color=" << (*it).fgColor().name() << endl; + if ((*it).bgColor().isValid()) + t << "bgcolor=" << (*it).bgColor().name() << endl; + + if ((*it).housePrice() > 0) + t << "houseprice=" << (*it).housePrice() << endl; + + if (!(*it).rentMath().isEmpty()) + t << "rentmath=" << (*it).rentMath() << endl; + } + + // now do the cards + + for (QValueList::Iterator it = cards.begin(); it != cards.end(); ++it) + { + t << endl << endl; + t << "" << endl << endl; + t << "groupname=" << (*it).name() << endl; + + for (CardStack::Iterator cit = (*it).begin(); cit != (*it).end(); ++cit) + { + t << endl << "[" << (*cit).name << "]" << endl; + QValueList::Iterator vit = (*cit).values.begin(); + for (QStringList::Iterator it = (*cit).keys.begin(); it != (*cit).keys.end(); ++it, ++vit) + { + QString key = (*it); + int value = (*vit); + + if (key == "collect") + { + value *= -1; + key = "pay"; + } + else if (key == "collecteach") + { + value *= -1; + key = "payeach"; + } + else if (key == "goback") + { + value *= -1; + key = "advance"; + } + + if (key == "outofjail" || key == "tojail" || key == "nextrr" || key == "nextutil") + value = 1; + + if (key == "outofjail") + { + t << "canbeowned=" << 1 << endl; + } + + t << key << "=" << value << endl; + } + } + } + + t << endl << endl; + + t << "" << endl; + + for (estate = estates.first(); estate; estate = estates.next()) + { + t << endl << QString("[%1]").arg(estate->name()) << endl; + + switch (estate->type()) + { + case Street: + if (!estate->group().isNull()) + t << "group=" << estate->group() << endl; + + if (estate->price() > 0) + t << "price=" << estate->price() << endl; + + for (int i = 0; i < 6; i++) + { + if (estate->rent(i) > 0) + t << "rent" << i << "=" << estate->rent(i) << endl; + } + break; + + case Tax: + if (estate->tax() > 0) + t << "tax=" << estate->tax() << endl; + if (estate->taxPercentage() > 0) + t << "taxpercentage=" << estate->taxPercentage() << endl; + break; + + case Jail: + t << "jail=1" << endl; + if (estate->forceBg().isValid()) + t << "bgcolor=" << estate->forceBg().name() << endl; + break; + + case ToJail: + t << "tojail=1" << endl; + if (estate->forceBg().isValid()) + t << "bgcolor=" << estate->forceBg().name() << endl; + break; + + case Cards: + t << "takecard=" << estate->takeCard() << endl; + break; + + case FreeParking: + t << "freeparking=1" << endl; + if (estate->forceBg().isValid()) + t << "bgcolor=" << estate->forceBg().name() << endl; + break; + } + + if (estate->passMoney() > 0) + t << "passmoney=" << estate->passMoney() << endl; + } + + f.flush(); + doCaption(false); +} + +void AtlanticDesigner::copy() +{ + copiedEstate = editor->theEstate(); +} + +void AtlanticDesigner::paste() +{ + ConfigEstate *estate = editor->theEstate(); + for (int i = 0; i < 6; i++) + estate->setRent(i, copiedEstate->rent(i)); + estate->setPrice(copiedEstate->price()); + estate->setTax(copiedEstate->tax()); + estate->setTaxPercentage(copiedEstate->taxPercentage()); + estate->setGroup(copiedEstate->group()); + estate->setTakeCard(copiedEstate->takeCard()); + estate->setType(copiedEstate->type()); + estate->setName(copiedEstate->name()); + estate->setPassMoney(copiedEstate->passMoney()); + + editor->setEstate(estate); + + groupsChanged(); +} + +void AtlanticDesigner::closeEvent(QCloseEvent *e) +{ + if (warnClose()) + return; + + saveMainWindowSettings(KGlobal::config(), "DesignerTopLevelWindow"); + recentAct->saveEntries(KGlobal::config(), "Designer recent files"); + + e->accept(); + kapp->quit(); +} + +void AtlanticDesigner::changeEstate(int index) +{ + if (index < 0 || index > max - 1) + return; + + changeEstate(estates.at(index)); +} + +void AtlanticDesigner::changeEstate(Estate *estate) +{ + if (!estate) + return; + + setFocus(); + + (void) editor->saveEstate(); + + editor->setEstate(static_cast(estate)); + movePlayer(estate); +} + +void AtlanticDesigner::movePlayer(Estate *estate) +{ + estateAct->setCurrentItem(estate->id()); + board->setFocus(); + m_player->setLocation(estate); + m_player->update(); +} + +// this will add a square to all sides +void AtlanticDesigner::larger() +{ + max += 4; + int sideLen = max/4; + + initBoard(); + + ConfigEstate *estate = 0; + for (int i = 0; i < max; ++i) + { + estate = estates.at(i); + estate->setEstateId(i); + board->addEstateView(estate); + + // make a newEstate + if ((i % sideLen - 1) == 0 || i == 1) + { + newEstate(i); + } + } + + updateJumpMenu(); + groupsChanged(); + updateBackground(); + + QTimer::singleShot(500, this, SLOT(setPlayerAtBeginning())); + doCaption(true); +} + +void AtlanticDesigner::smaller() +{ + if (max < 12) + return; + + max -= 4; + int sideLen = max/4; + + initBoard(); + + bool remove = true; + + ConfigEstate *estate = 0; + for (int i = 0; i < max; ++i) + { + // remove estate + if (((i % sideLen - 1) == 0 || i == 1) && remove) + { + estates.remove(i); + i--; + remove = false; + } + else + { + estate = estates.at(i); + estate->setEstateId(i); + board->addEstateView(estate); + + remove = true; + } + } + + updateJumpMenu(); + groupsChanged(); + updateBackground(); + QTimer::singleShot(500, this, SLOT(setPlayerAtBeginning())); + + doCaption(true); +} + +void AtlanticDesigner::modified() +{ + doCaption(true); +} + +void AtlanticDesigner::doCaption(bool modified) +{ + setCaption(filename.isNull()? i18n("Atlantik Gameboard Editor") : filename, modified); + isMod = modified; +} + +void AtlanticDesigner::editGroups() +{ + if (groupEditor.isNull()) + { + groupEditor = new GroupEditor(&groups, this); + groupEditor->show(); + + connect(groupEditor, SIGNAL(changed()), this, SLOT(modified())); + connect(groupEditor, SIGNAL(update()), this, SLOT(groupsChanged())); + connect(groupEditor, SIGNAL(update()), editor, SLOT(groupsChanged())); + } + else + groupEditor->raise(); +} + +void AtlanticDesigner::goChanged(int id) +{ + ConfigEstate *curEstate = 0; + for (curEstate = estates.first(); curEstate; curEstate = estates.next()) + if (curEstate->go() && curEstate->id() != id) + curEstate->setGo(false); +} + +void AtlanticDesigner::groupsChanged() +{ + ConfigEstate *curEstate = 0; + for (curEstate = estates.first(); curEstate; curEstate = estates.next()) + { + for (ConfigEstateGroupList::Iterator it = groups.begin(); it != groups.end(); ++it) + { + if ((*it).name() == curEstate->group() && curEstate->type() == Street) + { + curEstate->setBgColor((*it).bgColor().isValid()? (*it).bgColor() : boardInfo.bgColor); + curEstate->setColor((*it).fgColor()); + curEstate->update(); + break; + } + } + } +} + +void AtlanticDesigner::updateBackground() +{ + ConfigEstate *curEstate = 0; + for (curEstate = estates.first(); curEstate; curEstate = estates.next()) + { + if (curEstate->type() != Street || (curEstate->type() == Street && curEstate->group().isNull())) + { + curEstate->setColor(QColor()); + curEstate->setBgColor(boardInfo.bgColor); + } + + if (curEstate->forceBg().isValid() && (curEstate->type() == FreeParking || curEstate->type() == Jail || curEstate->type() == ToJail)) + { + curEstate->setBgColor(curEstate->forceBg()); + } + + curEstate->update(); + } +} + +void AtlanticDesigner::info() +{ + if (boardInfoDlg.isNull()) + { + // non-modal + boardInfoDlg = new BoardInfoDlg(true, &boardInfo, this, "Board Information", false); + boardInfoDlg->show(); + + connect(boardInfoDlg, SIGNAL(okClicked()), this, SLOT(updateBackground())); + connect(boardInfoDlg, SIGNAL(okClicked()), this, SLOT(modified())); + } + else + boardInfoDlg->raise(); +} + +// now some fun functions ;) + +void AtlanticDesigner::up() +{ + if (editor->upArrow()) + return; + int fourth = max / 4; + int estateId = editor->theEstate()->id() + 1; + int dest = estateId - 1; + + if (estateId <= 2*fourth && estateId > fourth) // left side + dest++; + else if (estateId > (3*fourth + 1)) // right side + dest--; + else if (estateId == 1) + dest = max - 1; + + changeEstate(dest); +} + +void AtlanticDesigner::down() +{ + if (editor->downArrow()) + return; + int fourth = max / 4; + int estateId = editor->theEstate()->id() + 1; + int dest = estateId - 1; + + if (estateId <= (2*fourth + 1) && estateId > (fourth + 1)) // left side + dest--; + else if (estateId > 3*fourth && estateId < max) // right side + dest++; + else if (estateId == max) + dest = 0; + + changeEstate(dest); +} + +void AtlanticDesigner::left() +{ + if (editor->leftArrow()) + return; + int fourth = max / 4; + int estateId = editor->theEstate()->id() + 1; + int dest = estateId - 1; + + if (estateId <= fourth) // bottom + dest++; + else if (estateId > (2*fourth + 1) && estateId <= (3*fourth + 1)) // top + dest--; + + changeEstate(dest); +} + +void AtlanticDesigner::right() +{ + if (editor->rightArrow()) + return; + int fourth = max / 4; + int estateId = editor->theEstate()->id() + 1; + int dest = estateId - 1; + + if (estateId <= (fourth + 1) && estateId != 1) // bottom + dest--; + else if (estateId > 2*fourth && estateId <= 3*fourth) // top + dest++; + + changeEstate(dest); +} + +#include "designer.moc" diff --git a/atlantikdesigner/designer/designer.h b/atlantikdesigner/designer/designer.h new file mode 100644 index 0000000..91dd7b4 --- /dev/null +++ b/atlantikdesigner/designer/designer.h @@ -0,0 +1,106 @@ +#ifndef ATLANTK_DESIGNER_H +#define ATLANTK_DESIGNER_H + +#include +#include +#include +#include +#include + +#include + +#include "boardinfo.h" +#include "group.h" +#include "editor.h" + +class EstateEdit; +class QCloseEvent; +class KListAction; +class KRecentFilesAction; +class Estate; +class Player; +class ConfigEstate; +class AtlantikBoard; + +class AtlanticDesigner : public KMainWindow +{ + Q_OBJECT + + public: + AtlanticDesigner(QWidget *parent = 0, const char *name = 0); + ~AtlanticDesigner(); + + protected: + void closeEvent(QCloseEvent *); + + public slots: + void modified(); + + private slots: + void open(); + void openRecent(const KURL &); + void openNew(); + void save(); + void saveAs(); + void copy(); + void paste(); + void changeEstate(int); + void changeEstate(Estate *); + void movePlayer(Estate *); + void setPlayerAtBeginning(); + void info(); + void editGroups(); + void groupsChanged(); + void goChanged(int); + void updateBackground(); + + void up(); + void down(); + void left(); + void right(); + + void smaller(); + void larger(); + + void updateJumpMenu(); + + private: + void openFile(const QString &); + bool warnClose(); + void initBoard(); + void initMembers(); + void initToken(); + bool firstBoard; + ConfigEstate *newEstate(int); + + QGuardedPtr editor; + QGuardedPtr layout; + QGuardedPtr board; + QGuardedPtr groupEditor; + QGuardedPtr boardInfoDlg; + EstateList estates; + KListAction *estateAct; + KRecentFilesAction *recentAct; + + QValueList cards; + BoardInfo boardInfo; + ConfigEstateGroupList groups; + + QString filename; + + ConfigEstate *copiedEstate; + + void doCaption(bool); + + int max; + QStringList types; + + Player *m_player; + + bool isMod; + + QColor defaultFg; + QColor defaultBg; +}; + +#endif diff --git a/atlantikdesigner/designer/editor.cpp b/atlantikdesigner/designer/editor.cpp new file mode 100644 index 0000000..f092254 --- /dev/null +++ b/atlantikdesigner/designer/editor.cpp @@ -0,0 +1,938 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "editor.h" + +ConfigEstate::ConfigEstate(int estateId) : Estate(estateId) +{ + m_rent[0] = m_rent[1] = m_rent[2] = m_rent[3] = m_rent[4] = m_rent[5] = 0; + m_type = m_price = m_tax = m_taxPercentage = m_passMoney = 0; + m_go = false; + m_group = "Default"; + m_changed = false; +} + +void ConfigEstate::setChanged(bool b) +{ + m_changed = b; +} + +void ConfigEstate::setEstateId(const int estateId) +{ + if (m_id != estateId) + { + m_id = estateId; + m_changed = true; + } +} + +void ConfigEstate::setType(const int type) +{ + if (m_type != type) + { + m_type = type; + m_changed = true; + } +} + +void ConfigEstate::setGroup(const QString &group) +{ + if (m_group != group) + { + m_group = group; + m_changed = true; + } +} + +void ConfigEstate::setPrice(int price) +{ + if (m_price != price) + { + m_price = price; + m_changed = true; + } +} + +void ConfigEstate::setRent(const int houses, const int rent) +{ + if (m_rent[houses] != rent) + { + m_rent[houses] = rent; + m_changed = true; + } +} + +void ConfigEstate::setTax(const int tax) +{ + if (m_tax != tax) + { + m_tax = tax; + m_changed = true; + } +} + +void ConfigEstate::setTaxPercentage(const int taxPercentage) +{ + if (m_taxPercentage != taxPercentage) + { + m_taxPercentage = taxPercentage; + m_changed = true; + } +} + +void ConfigEstate::setTakeCard(const QString &takeCard) +{ + if (m_takeCard != takeCard) + { + m_takeCard = takeCard; + m_changed = true; + } +} + +void ConfigEstate::setForceBg(const QColor &forceBg) +{ + if (m_forceBg != forceBg) + { + m_forceBg = forceBg; + m_changed = true; + } +} + +void ConfigEstate::setGo(const bool go) +{ + if (m_go != go) + { + m_go = go; + m_changed = true; + } +} + +void ConfigEstate::setPassMoney(const int passMoney) +{ + if (m_passMoney != passMoney) + { + m_passMoney = passMoney; + m_changed = true; + } +} + +/////////////////////////// + +QStringList types; + +EstateEdit::EstateEdit(ConfigEstateGroupList *newGroups, EstateList *estates, QValueList *cards, QWidget *parent, const char *name) + : QWidget(parent, name) +{ + groups = newGroups; + + types.append("pay"); + types.append("payeach"); + types.append("collect"); + types.append("collecteach"); + types.append("advanceto"); + types.append("advance"); + types.append("goback"); + types.append("tojail"); + types.append("outofjail"); + types.append("nextutil"); + types.append("nextrr"); + types.append("payhouse"); + types.append("payhotel"); + + oldType = -1; + estate = 0; + this->cards = cards; + this->estates = estates; + ready = false; + locked = false; + + connect(this, SIGNAL(somethingChanged()), this, SLOT(saveEstate())); + + layout = new QGridLayout(this, 7, 1, KDialog::marginHint(), KDialog::spacingHint()); + nameEdit = new QLineEdit(this, "Name Edit"); + layout->addWidget(nameEdit, 0, 0); + connect(nameEdit, SIGNAL(returnPressed()), this, SIGNAL(somethingChanged())); + + confDlg = 0; + + layout->setRowStretch(2, 2); + + layout->addWidget(new KSeparator(this), 3, 0); + + QHBoxLayout *typeLayout = new QHBoxLayout(KDialog::spacingHint()); + layout->addLayout(typeLayout, 4, 0); + + QLabel *typeLabel = new QLabel(i18n("Type:"), this); + typeLayout->addWidget(typeLabel); + typeCombo = new KComboBox(false, this, "Type Combo"); + typeLayout->addWidget(typeCombo); + connect(typeCombo, SIGNAL(activated(int)), this, SIGNAL(somethingChanged())); + connect(typeCombo, SIGNAL(activated(int)), this, SIGNAL(updateBackground())); + + goCheck = new QCheckBox(i18n("This estate is 'Go'"), this); + connect(goCheck, SIGNAL(toggled(bool)), this, SIGNAL(somethingChanged())); + connect(goCheck, SIGNAL(toggled(bool)), this, SLOT(goToggled(bool))); + layout->addWidget(goCheck, 5, 0); + + QHBoxLayout *passMoneyLayout = new QHBoxLayout(KDialog::spacingHint()); + layout->addLayout(passMoneyLayout, 6, 0); + QLabel *passMoneyLabel = new QLabel(i18n("Pass money:"), this); + passMoneyLayout->addWidget(passMoneyLabel); + passMoney = new QSpinBox(0, 3000, 10, this); + passMoney->setSpecialValueText(i18n("None")); + passMoney->setSuffix("$"); + passMoneyLayout->addWidget(passMoney); + + QStringList estateTypes(i18n("Street")); + estateTypes.append(i18n("Cards")); + estateTypes.append(i18n("Free Parking")); + estateTypes.append(i18n("Go to Jail")); + estateTypes.append(i18n("Tax")); + estateTypes.append(i18n("Jail")); + typeCombo->insertStringList(estateTypes); +} + +void EstateEdit::aboutToDie() +{ + delete confDlg; + confDlg = 0; +} + +void EstateEdit::setReady(bool ready) +{ + this->ready = ready; +} + +void EstateEdit::resizeEvent(QResizeEvent *) +{ + emit resized(); +} + +void EstateEdit::setEstate(ConfigEstate *_estate) +{ + if (!_estate) + return; + + // why the hell is this here? :-) + while (1) + if (!locked) + break; + + estate = _estate; + + ready = false; + nameEdit->setText(estate->name()); + typeCombo->setCurrentItem(estate->type()); + goCheck->setChecked(estate->go()); + passMoney->setValue(estate->passMoney()); + + ready = true; + + saveEstate(true); +} + +ConfigEstate *EstateEdit::saveEstate(bool superficial) +{ + if (!estate || !ready) + return 0; + + locked = true; + + EstateType curType = (EstateType)typeCombo->currentItem(); + + if (!superficial) + { + confDlg->slotOk(); + + estate->setType(curType); + estate->setName(nameEdit->text()); + estate->setGo(goCheck->isChecked()); + estate->setPassMoney(passMoney->value()); + } + + if (curType != Street) + { + } + + if (!superficial) + estate->update(); + + configure(); + + locked = false; + + return estate; +} + +void EstateEdit::configure() +{ + if (oldType == typeCombo->currentItem()) + { + confDlg->slotUpdate(estate); + return; + } + + delete confDlg; + + switch (estate->type()) + { + case Street: + confDlg = new StreetDlg(groups, this); + break; + + case Tax: + confDlg = new TaxDlg(this); + break; + + case Cards: + confDlg = new CardsDlg(estates, cards, this); + break; + + case Jail: + case ToJail: + case FreeParking: + confDlg = new GenericDlg(this); + break; + + default: + confDlg = new EstateDlg(this); + break; + } + + confDlg->slotUpdate(estate); + + connect(confDlg, SIGNAL(updateBackground()), this, SIGNAL(updateBackground())); + + layout->addWidget(confDlg, 1, 0); + confDlg->show(); + + oldType = typeCombo->currentItem(); +} + +void EstateEdit::groupsChanged() +{ + confDlg->groupsChanged(); +} + +void EstateEdit::goToggled(bool on) +{ + if (on) + { + emit goChecked(estate->id()); + } +} + +bool EstateEdit::upArrow()const +{ + return (nameEdit->hasFocus() || typeCombo->hasFocus()); +} + +bool EstateEdit::downArrow()const +{ + return upArrow(); +} + +bool EstateEdit::leftArrow()const +{ + if (nameEdit->hasFocus()) + { + nameEdit->setCursorPosition(nameEdit->cursorPosition() - 1); + return true; + } + return false; +} + +bool EstateEdit::rightArrow()const +{ + if (nameEdit->hasFocus()) + { + nameEdit->setCursorPosition(nameEdit->cursorPosition() + 1); + return true; + } + return false; +} + +///////////////////////////////// + +TaxDlg::TaxDlg(QWidget *parent, char *name) + : EstateDlg(parent, name) +{ + QGridLayout *taxBox = new QGridLayout(this, 2, 2, KDialog::marginHint(), KDialog::spacingHint()); + taxBox->addWidget(new QLabel(i18n("Fixed tax:"), this), 0, 0); + taxBox->addWidget(tax = new QSpinBox(0, 3000, 1, this), 0, 1); + tax->setSpecialValueText(i18n("None")); + tax->setSuffix("$"); + taxBox->addWidget(new QLabel(i18n("Percentage tax:"), this), 1, 0); + taxBox->addWidget(taxPercentage = new QSpinBox(0, 100, 1, this), 1, 1); + taxPercentage->setSpecialValueText(i18n("None")); + taxPercentage->setSuffix("%"); +} + +void TaxDlg::save() +{ + estate->setTax(tax->value()); + estate->setTaxPercentage(taxPercentage->value()); +} + +void TaxDlg::update() +{ + tax->setValue(estate->tax()); + taxPercentage->setValue(estate->taxPercentage()); +} + +///////////////////////////////// + +GenericDlg::GenericDlg(QWidget *parent, char *name) + : EstateDlg(parent, name) +{ + QHBoxLayout *layout = new QHBoxLayout(this, KDialog::spacingHint()); + layout->addWidget(new QLabel(i18n("Background:"), this)); + + col = new KColorButton(this); + layout->addWidget(col); +} + +void GenericDlg::save() +{ + estate->setForceBg(col->color()); + emit updateBackground(); +} + +void GenericDlg::update() +{ + col->setColor(estate->forceBg()); +} + +///////////////////////////////// + +CardsDlg::CardsDlg(EstateList *newEstates, QValueList *newCards, QWidget *parent, char *name) + : EstateDlg(parent, name) +{ + estates = newEstates; + stacks = newCards; + + view = 0; + + vlayout = new QVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint()); + + QHBoxLayout *layout = new QHBoxLayout(vlayout, KDialog::spacingHint()); + + KPushButton *addB = new KPushButton(i18n("&New Stack"), this); + connect(addB, SIGNAL(clicked()), this, SLOT(addStack())); + layout->addWidget(addB); + layout->addStretch(); + + layout->addWidget(new QLabel(i18n("Cards from"), this)); + QStringList cardNames; + for (QValueList::Iterator it = stacks->begin(); it != stacks->end(); ++it) + cardNames.append((*it).name()); + + cards = new QComboBox(this); + cards->insertStringList(cardNames); + layout->addWidget(cards); + connect(cards, SIGNAL(activated(const QString &)), this, SLOT(updateView(const QString &))); + + vlayout->addWidget(new KSeparator(this)); +} + +void CardsDlg::addStack() +{ + bool ok; + QString name = KLineEditDlg::getText(i18n("Add Stack"), i18n("Enter the name of the new stack:"), QString::null, &ok, this); + if (ok) + { + for (QValueList::Iterator it = stacks->begin(); it != stacks->end(); ++it) + { + if ((*it).name() == name) + { + KMessageBox::information(this, i18n("That name is already on the list.")); + return; + } + } + + stacks->append(CardStack(name)); + cards->insertItem(name); + cards->setCurrentText(name); + updateView(name); + } +} + +void CardsDlg::updateView(const QString &curName) +{ + CardStack *curStack = 0; + for (QValueList::Iterator it = stacks->begin(); it != stacks->end(); ++it) + if ((*it).name() == curName) + curStack = &(*it); + + if (!curStack) + return; + + delete view; + view = new CardView(estates, curStack, this); + vlayout->addWidget(view); + view->show(); +} + +void CardsDlg::save() +{ + estate->setTakeCard(cards->currentText()); +} + +void CardsDlg::update() +{ + if (!estate->takeCard().isNull()) + { + cards->setCurrentText(estate->takeCard()); + updateView(estate->takeCard()); + } + else + cards->setCurrentItem(-1); +} + +///////////////////////////////// + +ChooseWidget::ChooseWidget(EstateList *estates, int id, Card *card, QWidget *parent, char *name) + : QWidget (parent, name) +{ + this->id = id; + this->card = card; + this->estates = estates; + + value = 0; + estate = 0; + number = true; + prevNumber = true; + init = true; + + value = 0; + + hlayout = new QHBoxLayout(this, KDialog::spacingHint()); + typeCombo = new KComboBox(this); + QStringList _types(i18n("Pay")); + _types.append(i18n("Pay Each Player")); + _types.append(i18n("Collect")); + _types.append(i18n("Collect From Each Player")); + _types.append(i18n("Advance To")); + _types.append(i18n("Advance")); + _types.append(i18n("Go Back")); + _types.append(i18n("Go to Jail")); + _types.append(i18n("Get out of Jail Free Card")); + _types.append(i18n("Advance to Nearest Utility")); + _types.append(i18n("Advance to Nearest Railroad")); + _types.append(i18n("Pay for Each House")); + _types.append(i18n("Pay for Each Hotel")); + typeCombo->insertStringList(_types); + hlayout->addWidget(typeCombo); + connect(typeCombo, SIGNAL(activated(int)), this, SLOT(typeChanged(int))); + + hlayout->addStretch(); +} + +void ChooseWidget::valueChanged(int i) +{ + if (!value) + return; + (*card->values.at(id)) = i; + value->setValue(i); +} + +void ChooseWidget::estateChanged(int i) +{ + if (!estate) + return; + + (*card->values.at(id)) = i; + estate->setCurrentItem(i); +} + +void ChooseWidget::typeChanged(int i) +{ + QString key = (*types.at(i)); + + (*card->keys.at(id)) = key; + typeCombo->setCurrentItem(i); + + number = key != "advanceto"; + + if (prevNumber == number && !init) + goto Skipped; + + if (number) + { + delete estate; + estate = 0; + + value = new QSpinBox(0, 2000, (key == "advance" || key == "goback")? 1 : 5, this); + + hlayout->addWidget(value); + connect(value, SIGNAL(valueChanged(int)), this, SLOT(valueChanged(int))); + + value->show(); + } + else + { + delete value; + value = 0; + estate = new KComboBox(this); + ConfigEstate *curestate = 0; + QStringList estateStrings; + for (curestate = estates->first(); curestate; curestate = estates->next()) + estateStrings.append(curestate->name()); + estate->insertStringList(estateStrings); + connect(estate, SIGNAL(activated(int)), this, SLOT(estateChanged(int))); + + hlayout->addWidget(estate); + estate->show(); + } + + prevNumber = number; + +Skipped: + init = false; + + if (!number) + return; + + bool boolean = (key == "outofjail" || key == "tojail" || key == "nextrr" || key == "nextutil"); + if (boolean) + { + value->setValue(1); + valueChanged(1); + } + value->setEnabled(!boolean); + + QString suffix = ""; + QString prefix = ""; + + // first four types are money, pay, payeach, collect, collecteach + if (i < 4 || key == "payhouse" || key == "payhotel") + suffix = "$"; + else if (key == "advance" || key == "goback") + suffix = i18n("Estate(s)").prepend(" "); + + value->setPrefix(prefix); + value->setSuffix(suffix); +} + +///////////////////////////////// + +CardView::CardView(EstateList *estates, CardStack *stack, QWidget *parent, char *name) : QWidget(parent, name) +{ + card = 0; + + this->stack = stack; + this->estates = estates; + + choosies.setAutoDelete(true); + + layout = new QVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint()); + QHBoxLayout *hlayout = new QHBoxLayout(layout, KDialog::spacingHint()); + + addButton = new KPushButton(i18n("&Add Card..."), this); + connect(addButton, SIGNAL(clicked()), this, SLOT(add())); + hlayout->addWidget(addButton); + hlayout->addStretch(); + renameButton = new KPushButton(i18n("&Rename..."), this); + connect(renameButton, SIGNAL(clicked()), this, SLOT(rename())); + hlayout->addWidget(renameButton); + hlayout->addStretch(); + delButton = new KPushButton(i18n("&Delete"), this); + connect(delButton, SIGNAL(clicked()), this, SLOT(del())); + hlayout->addWidget(delButton); + + List = new KListBox(this); + layout->addWidget(List); + connect(List, SIGNAL(highlighted(int)), this, SLOT(selected(int))); + + // it gets very big (and won't shrink) otherwise + List->setMaximumHeight(90); + + hlayout = new QHBoxLayout(layout, KDialog::spacingHint()); + moreButton = new KPushButton(i18n("&More Properties"), this); + connect(moreButton, SIGNAL(clicked()), this, SLOT(more())); + hlayout->addWidget(moreButton); + hlayout->addStretch(); + lessButton = new KPushButton(i18n("&Fewer Properties"), this); + connect(lessButton, SIGNAL(clicked()), this, SLOT(less())); + hlayout->addWidget(lessButton); + + for (CardStack::Iterator it = stack->begin(); it != stack->end(); ++it) + List->insertItem((*it).name); + + updateButtonsEnabled(); +} + +void CardView::more() +{ + if (!card) + return; + + card->keys.append("pay"); + card->values.append(0); + ChooseWidget *newChooseWidget = new ChooseWidget(estates, choosies.count(), card, this); + newChooseWidget->typeChanged(0); + newChooseWidget->valueChanged(0); + + choosies.append(newChooseWidget); + layout->addWidget(newChooseWidget); + + newChooseWidget->show(); + + updateButtonsEnabled(); +} + +void CardView::less() +{ + if (List->count() <= 0 || choosies.count() <= 0) + return; + + choosies.removeLast(); + card->keys.pop_back(); + card->values.pop_back(); + + updateButtonsEnabled(); +} + +void CardView::add() +{ + bool ok = false; + QString name = KLineEditDlg::getText(i18n("Add Card"), i18n("Enter the name of the new card:"), QString::null, &ok, this); + if (ok) + List->insertItem(name, 0); + + choosies.clear(); + + stack->prepend(Card(name)); + + List->setCurrentItem(0); + + more(); + + updateButtonsEnabled(); +} + +void CardView::rename() +{ + int curItem = List->currentItem(); + if (curItem < 0) + return; + + bool ok = false;; + QString name = KLineEditDlg::getText(i18n("Add Card"), i18n("Enter the name of the new card:"), (*stack->at(curItem)).name, &ok, this); + if (ok) + { + (*stack->at(curItem)).name = name; + List->changeItem(name, curItem); + } + + updateButtonsEnabled(); +} + +void CardView::del() +{ + int curItem = List->currentItem(); + + // for some reason, crashes if count == 0 + if (curItem < 0 || List->count() <= 1) + return; + + List->removeItem(curItem); + stack->remove(stack->at(curItem)); + choosies.clear(); + + updateButtonsEnabled(); +} + +void CardView::selected(int i) +{ + choosies.clear(); + + card = &(*stack->at(i)); + unsigned int num = card->keys.count(); + + QValueList::Iterator vit = card->values.begin(); + for (QStringList::Iterator it = card->keys.begin(); it != card->keys.end(); ++it) + { + ChooseWidget *newChooseWidget = new ChooseWidget(estates, choosies.count(), card, this); + + choosies.append(newChooseWidget); + layout->addWidget(newChooseWidget); + + newChooseWidget->show(); + + newChooseWidget->typeChanged(types.findIndex(*it)); + newChooseWidget->valueChanged(*vit); + newChooseWidget->estateChanged(*vit); + + ++vit; + } + + if (num == 0) + { + card->values.clear(); + more(); + } + + updateButtonsEnabled(); +} + +void CardView::updateButtonsEnabled() +{ + int curItem = List->currentItem(); + int count = List->count(); + delButton->setEnabled(!(curItem < 0 || count <= 1)); + renameButton->setEnabled(!(curItem < 0)); + moreButton->setEnabled(card); + lessButton->setEnabled(!(count <= 0 || choosies.count() <= 0)); +} + +///////////////////////////////// + +StreetDlg::StreetDlg(ConfigEstateGroupList *newGroups, QWidget *parent, char *name) + : EstateDlg(parent, name) +{ + groups = newGroups; + + QVBoxLayout *bigbox = new QVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint()); + + QVGroupBox *RentPage = new QVGroupBox(i18n("&Rent by Number of Houses"), this); + RentPage->setInsideSpacing(KDialog::spacingHint()); + RentPage->setInsideMargin(KDialog::marginHint()); + bigbox->addWidget(RentPage); + QWidget *topRent = new QWidget(RentPage); + QGridLayout *rentBox = new QGridLayout(topRent, 3, 3, KDialog::spacingHint()); + rentBox->addWidget(new QLabel(i18n("None:"), topRent), 0, 0); + rentBox->addWidget(new QLabel(i18n("One:"), topRent), 0, 1); + rentBox->addWidget(new QLabel(i18n("Two:"), topRent), 0, 2); + rentBox->addWidget(new QLabel(i18n("Three:"), topRent), 2, 0); + rentBox->addWidget(new QLabel(i18n("Four:"), topRent), 2, 1); + rentBox->addWidget(new QLabel(i18n("Hotel:"), topRent), 2, 2); + + rentBox->addWidget(houses0 = new QSpinBox(0, 3000, 1, topRent), 1, 0); + rentBox->addWidget(houses1 = new QSpinBox(0, 3000, 1, topRent), 1, 1); + rentBox->addWidget(houses2 = new QSpinBox(0, 3000, 1, topRent), 1, 2); + rentBox->addWidget(houses3 = new QSpinBox(0, 3000, 1, topRent), 3, 0); + rentBox->addWidget(houses4 = new QSpinBox(0, 3000, 1, topRent), 3, 1); + rentBox->addWidget(houses5 = new QSpinBox(0, 3000, 1, topRent), 3, 2); + houses0->setSuffix(i18n("$")); + houses0->setSpecialValueText(i18n("None")); + houses1->setSuffix(i18n("$")); + houses1->setSpecialValueText(i18n("None")); + houses2->setSuffix(i18n("$")); + houses2->setSpecialValueText(i18n("None")); + houses3->setSuffix(i18n("$")); + houses3->setSpecialValueText(i18n("None")); + houses4->setSuffix(i18n("$")); + houses4->setSpecialValueText(i18n("None")); + houses5->setSuffix(i18n("$")); + houses5->setSpecialValueText(i18n("None")); + + QGridLayout *pricesBox = new QGridLayout(bigbox, 2, 2, KDialog::spacingHint()); + pricesBox->addWidget(new QLabel(i18n("Price:"), this), 0, 0); + pricesBox->addWidget(price = new QSpinBox(0, 3000, 25, this), 0, 1); + price->setSpecialValueText(i18n("None")); + price->setSuffix(i18n("$")); + + QLabel *groupLabel = new QLabel(i18n("Group:"), this); + pricesBox->addWidget(groupLabel, 1, 0); + groupCombo = new KComboBox(this, "Group Combo"); + groupUpdate(); + connect(groupCombo, SIGNAL(activated(const QString &)), this, SLOT(groupChanged(const QString &))); + + pricesBox->addWidget(groupCombo, 1, 1); +} + +void StreetDlg::groupChanged(const QString &groupName) +{ + for (ConfigEstateGroupList::Iterator it = groups->begin(); it != groups->end(); ++it) + { + if ((*it).name() == groupName) + { + if ( (*it).fgColor().isValid() ) + estate->setColor((*it).fgColor()); + if ( (*it).bgColor().isValid() ) + estate->setBgColor((*it).bgColor()); + estate->update(); + + break; + } + } +} + +void StreetDlg::groupUpdate() +{ + QString curGroupName = groupCombo->currentText(); + + QStringList newGroups; + for (ConfigEstateGroupList::Iterator it = groups->begin(); it != groups->end(); ++it) + newGroups.append((*it).name()); + + groupCombo->clear(); + groupCombo->insertStringList(newGroups); + + if (!curGroupName.isNull()) + { + groupCombo->setCurrentText(curGroupName); + groupChanged(curGroupName); + } +} + +void StreetDlg::save() +{ + estate->setRent(0, houses0->value()); + estate->setRent(1, houses1->value()); + estate->setRent(2, houses2->value()); + estate->setRent(3, houses3->value()); + estate->setRent(4, houses4->value()); + estate->setRent(5, houses5->value()); + estate->setPrice(price->value()); + estate->setGroup(groupCombo->currentText()); +} + +void StreetDlg::update() +{ + houses0->setValue(estate->rent(0)); + houses1->setValue(estate->rent(1)); + houses2->setValue(estate->rent(2)); + houses3->setValue(estate->rent(3)); + houses4->setValue(estate->rent(4)); + houses5->setValue(estate->rent(5)); + + price->setValue(estate->price()); + + if (estate->group().isEmpty()) + { + groupCombo->setCurrentText("Default"); + estate->setGroup("Default"); + } + else + groupCombo->setCurrentText(estate->group()); + + groupChanged(estate->group()); +} + +#include "editor.moc" diff --git a/atlantikdesigner/designer/editor.h b/atlantikdesigner/designer/editor.h new file mode 100644 index 0000000..be6d63a --- /dev/null +++ b/atlantikdesigner/designer/editor.h @@ -0,0 +1,310 @@ +#ifndef ATLANTIK_EDITOR_H +#define ATLANTIK_EDITOR_H + +#include +#include +#include +#include + +#include + +#include "group.h" + +class QCheckBox; +class QGridLayout; +class QLineEdit; +class QSpinBox; + +class KColorButton; +class KComboBox; +class KListBox; +class KPushButton; + +enum EstateType { Street = 0, Cards, FreeParking, ToJail, Tax, Jail }; + +class ConfigEstate : public Estate +{ + public: + ConfigEstate(int estateId); + void setEstateId(const int estateId); + int type()const { return m_type; } + void setType(const int type); + const QString &group() { return m_group; } + void setGroup(const QString &group); + int price()const { return m_price; } + void setPrice(int); + int rent(int _h)const { return m_rent[_h]; } + void setRent(const int, const int); + int tax()const { return m_tax; } + void setTax(const int); + int taxPercentage() { return m_taxPercentage; } + void setTaxPercentage(const int); + const QString &takeCard() { return m_takeCard; } + void setTakeCard(const QString &); + const QColor &forceBg() { return m_forceBg; } + void setForceBg(const QColor &); + bool go()const { return m_go; } + void setGo(const bool); + int passMoney()const { return m_passMoney; } + void setPassMoney(const int); + + void setChanged(bool); + + private: + int m_type; + QString m_group; + int m_rent[6]; + int m_price; + int m_tax; + int m_taxPercentage; + QString m_takeCard; + QColor m_forceBg; + bool m_go; + int m_passMoney; +}; +typedef QPtrList EstateList; + +struct Card +{ + Card() {} + Card(const QString &newName) { name = newName; } + QString name; + QStringList keys; + QValueList values; +}; +class CardStack : public QValueList +{ + public: + CardStack() {} + CardStack(const QString &newName) { setName(newName); } + const QString &name() { return m_name; } + void setName(const QString &newName) { m_name = newName; } + + private: + QString m_name; +}; + +class EstateDlg : public QWidget +{ + Q_OBJECT + + public: + EstateDlg(QWidget *parent = 0, char *name = 0) : QWidget(parent, name) { estate = 0; } + + signals: + void updateBackground(); + + public slots: + virtual void slotOk() { save(); } + void slotUpdate(ConfigEstate *newEstate) { estate = newEstate; if (estate) update(); } + void groupsChanged() { groupUpdate(); } + + protected: + virtual void update() {} + virtual void save() {} + virtual void groupUpdate() {} + ConfigEstate *estate; +}; + +class EstateEdit : public QWidget +{ + Q_OBJECT + + public: + EstateEdit(ConfigEstateGroupList *, EstateList *, QValueList *, QWidget *parent = 0, const char *name = 0); + ConfigEstate *theEstate() { return estate; } + bool upArrow()const; + bool downArrow()const; + bool leftArrow()const; + bool rightArrow()const; + void aboutToDie(); + void setReady(bool); + + public slots: + void setEstate(ConfigEstate *); + ConfigEstate *saveEstate(bool superficial = false); + void groupsChanged(); + + signals: + void somethingChanged(); + void modified(); + void updateBackground(); + void goChecked(int id); + void resized(); + + protected: + void resizeEvent(QResizeEvent *); + + private slots: + void configure(); + void goToggled(bool); + + private: + KComboBox *typeCombo; + QLineEdit *nameEdit; + QCheckBox *goCheck; + QSpinBox *passMoney; + QWidget *centerWidget; + QGridLayout *layout; + + EstateList *estates; + QValueList *cards; + ConfigEstateGroupList *groups; + + ConfigEstate *estate; + + EstateDlg *confDlg; + + int oldType; + + bool ready; + bool locked; +}; + +class ChooseWidget : public QWidget +{ + Q_OBJECT + + public: + ChooseWidget(EstateList *, int id, Card *, QWidget *parent = 0, char *name = 0); + + public slots: + void typeChanged(int); + void valueChanged(int); + void estateChanged(int); + + private: + Card *card; + KComboBox *typeCombo; + QSpinBox *value; + KComboBox *estate; + bool number; + bool prevNumber; + bool init; + QHBoxLayout *hlayout; + + EstateList *estates; + + int id; +}; + +class CardView : public QWidget +{ + Q_OBJECT + + public: + CardView(EstateList *, CardStack *, QWidget *parent = 0, char *name = 0); + + private slots: + void selected(int); + void add(); + void del(); + void rename(); + void more(); + void less(); + void updateButtonsEnabled(); + + private: + KListBox *List; + KPushButton *addButton; + KPushButton *renameButton; + KPushButton *delButton; + KPushButton *moreButton; + KPushButton *lessButton; + + EstateList *estates; + + QVBoxLayout *layout; + + Card *card; + + CardStack *stack; + QPtrList choosies; +}; + +class TaxDlg : public EstateDlg +{ + Q_OBJECT + + public: + TaxDlg(QWidget *parent = 0, char *name = 0); + + protected: + virtual void save(); + virtual void update(); + + private: + QSpinBox *tax; + QSpinBox *taxPercentage; +}; + +class GenericDlg : public EstateDlg +{ + Q_OBJECT + + public: + GenericDlg(QWidget *parent = 0, char *name = 0); + + protected: + virtual void save(); + virtual void update(); + + private: + KColorButton *col; +}; + +class CardsDlg : public EstateDlg +{ + Q_OBJECT + + public: + CardsDlg(EstateList *, QValueList *, QWidget *parent = 0, char *name = 0); + + protected: + virtual void save(); + virtual void update(); + + private slots: + void addStack(); + void updateView(const QString &); + + private: + QValueList *stacks; + EstateList *estates; + + QComboBox *cards; + CardView *view; + QVBoxLayout *vlayout; +}; + +class StreetDlg : public EstateDlg +{ + Q_OBJECT + + public: + StreetDlg(ConfigEstateGroupList *, QWidget *parent = 0, char *name = 0); + + protected: + virtual void save(); + virtual void update(); + virtual void groupUpdate(); + + private slots: + void groupChanged(const QString &); + + private: + QSpinBox *houses0; + QSpinBox *houses1; + QSpinBox *houses2; + QSpinBox *houses3; + QSpinBox *houses4; + QSpinBox *houses5; + QSpinBox *price; + KComboBox *groupCombo; + + ConfigEstateGroupList *groups; + + ConfigEstateGroup *curGroup(); +}; + +#endif diff --git a/atlantikdesigner/designer/group.cpp b/atlantikdesigner/designer/group.cpp new file mode 100644 index 0000000..41f7c6f --- /dev/null +++ b/atlantikdesigner/designer/group.cpp @@ -0,0 +1,242 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "group.h" + +GroupEditor::GroupEditor(ConfigEstateGroupList *newList, QWidget *parent) + : KDialogBase(KDialogBase::Plain, i18n("Group Editor"), Ok|Apply|Cancel, Ok, parent, "Group Editor", false, true), mylist(*newList) +{ + setWFlags(WDestructiveClose); + list = newList; + + QFrame *page = plainPage(); + QHBoxLayout *hlayout = new QHBoxLayout(page, marginHint(), spacingHint()); + + groups = new KListBox(page); + hlayout->addWidget(groups); + connect(groups, SIGNAL(highlighted(QListBoxItem *)), this, SLOT(updateSettings(QListBoxItem *))); + QStringList newgroups; + for (ConfigEstateGroupList::Iterator it = list->begin(); it != list->end(); ++it) + newgroups.append((*it).name()); + groups->insertStringList(newgroups); + connect(groups, SIGNAL(selectionChanged()), this, SLOT(selectionChanged())); + + QVBoxLayout *vlayout = new QVBoxLayout(hlayout, spacingHint()); + colorGroupBox = new QVGroupBox(i18n("&Colors"), page); + vlayout->addWidget(colorGroupBox); + + (void) new QLabel(i18n("Foreground:"), colorGroupBox); + fgButton = new KColorButton(colorGroupBox, "Foreground Button"); + connect(fgButton, SIGNAL(changed(const QColor &)), this, SLOT(fgChanged(const QColor &))); + connect(fgButton, SIGNAL(changed(const QColor &)), this, SIGNAL(changed())); + + (void) new QLabel(i18n("Background:"), colorGroupBox); + bgButton = new KColorButton(colorGroupBox, "Background Button"); + connect(bgButton, SIGNAL(changed(const QColor &)), this, SLOT(bgChanged(const QColor &))); + connect(bgButton, SIGNAL(changed(const QColor &)), this, SIGNAL(changed())); + + pricesGroupBox = new QVGroupBox(i18n("&Prices"), page); + vlayout->addWidget(pricesGroupBox); + + pricesWidget = new QWidget(pricesGroupBox); + QGridLayout *pricesLayout = new QGridLayout(pricesWidget, 2, 2, 0, spacingHint()); + pricesLayout->addWidget(new QLabel(i18n("House price:"), pricesWidget), 0, 0); + pricesLayout->addWidget(housePrice = new QSpinBox(0, 3000, 25, pricesWidget), 0, 1); + housePrice->setSpecialValueText(i18n("None")); + housePrice->setSuffix(i18n("$")); + connect(housePrice, SIGNAL(valueChanged(int)), this, SLOT(housePriceChanged(int))); + + pricesLayout->addWidget(new QLabel(i18n("Global price:"), pricesWidget), 1, 0); + pricesLayout->addWidget(globalPrice = new QSpinBox(0, 3000, 25, pricesWidget), 1, 1); + globalPrice->setSpecialValueText(i18n("None")); + globalPrice->setSuffix(i18n("$")); + connect(globalPrice, SIGNAL(valueChanged(int)), this, SLOT(globalPriceChanged(int))); + + dynamicGroupBox = new QVGroupBox(i18n("&Dynamic Rent"), page); + vlayout->addWidget(dynamicGroupBox); + + mathWidget = new QWidget(dynamicGroupBox); + QGridLayout *mathLayout = new QGridLayout(mathWidget, 2, 2, 0, spacingHint()); + mathLayout->addWidget(new QLabel(i18n("Add rent variable:"), mathWidget), 0, 0); + mathLayout->addWidget(new QLabel(i18n("Expression:"), mathWidget), 1, 0); + + QComboBox *rentVarCombo = new QComboBox(mathWidget); + QStringList vars; + vars << "DICE"; + vars << "HOUSES"; + vars << "GROUPOWNED"; + rentVarCombo->insertStringList(vars); + mathLayout->addWidget(rentVarCombo, 0, 1); + + rentMathEdit = new KLineEdit(mathWidget); + connect(rentMathEdit, SIGNAL(textChanged(const QString &)), this, SLOT(rentMathChanged(const QString &))); + connect(rentVarCombo, SIGNAL(activated(const QString &)), rentMathEdit, SLOT(insert(const QString &))); + mathLayout->addWidget(rentMathEdit, 1, 1); + + QHBoxLayout *buttonlayout = new QHBoxLayout(vlayout, spacingHint()); + KPushButton *addB = new KPushButton(i18n("&Add..."), page); + buttonlayout->addWidget(addB); + connect(addB, SIGNAL(clicked()), this, SLOT(add())); + + removeB = new KPushButton(i18n("&Remove"), page); + buttonlayout->addWidget(removeB); + connect(removeB, SIGNAL(clicked()), this, SLOT(remove())); + + selectionChanged(); +} + +void GroupEditor::add() +{ + bool ok; + QString name = KLineEditDlg::getText(i18n("Add Group"), i18n("Enter the name of the new group:"), QString::null, &ok, this); + if (ok) + { + for (ConfigEstateGroupList::Iterator it = mylist.begin(); it != mylist.end(); ++it) + { + if ((*it).name() == name) + { + KMessageBox::information(this, i18n("That group is already on the list.")); + return; + } + } + + mylist.append(ConfigEstateGroup(name)); + groups->insertItem(name); + + emit changed(); + } +} + +void GroupEditor::remove() +{ + QString curText = groups->currentText(); + if (!curText.isNull()) + { + groups->removeItem(groups->currentItem()); + for (ConfigEstateGroupList::Iterator it = mylist.begin(); it != mylist.end(); ++it) + { + if ((*it).name() == curText) + { + mylist.remove(it); + break; + } + } + + emit changed(); + } +} + +void GroupEditor::updateSettings(QListBoxItem *item) +{ + if (!mylist.size()) + return; + + if (!item) + return; + + for (ConfigEstateGroupList::Iterator it = mylist.begin(); it != mylist.end() ; ++it) + { + if ((*it).name() == item->text()) + { + fgButton->setColor((*it).fgColor()); + bgButton->setColor((*it).bgColor()); + housePrice->setValue((*it).housePrice()); + globalPrice->setValue((*it).globalPrice()); + rentMathEdit->setText((*it).rentMath()); + break; + } + } +} + +ConfigEstateGroup *GroupEditor::currentGroup() +{ + QListBoxItem *item = groups->item(groups->currentItem()); + if (!item) + return 0; + + for (ConfigEstateGroupList::Iterator it = mylist.begin(); it != mylist.end(); ++it) + if ((*it).name() == item->text()) + return &(*it); + + return 0; +} + +void GroupEditor::fgChanged(const QColor &color) +{ + ConfigEstateGroup *group = currentGroup(); + if (group) + group->setFgColor(color); +} + +void GroupEditor::bgChanged(const QColor &color) +{ + ConfigEstateGroup *group = currentGroup(); + if (group) + group->setBgColor(color); +} + +void GroupEditor::housePriceChanged(int newValue) +{ + ConfigEstateGroup *group = currentGroup(); + if (group) + group->setHousePrice(newValue); +} + +void GroupEditor::globalPriceChanged(int newValue) +{ + ConfigEstateGroup *group = currentGroup(); + if (group) + group->setGlobalPrice(newValue); +} + +void GroupEditor::rentMathChanged(const QString &newValue) +{ + ConfigEstateGroup *group = currentGroup(); + if (group) + { + group->setRentMath(newValue); + } +} + +void GroupEditor::slotApply() +{ + *list = mylist; + + KDialogBase::slotApply(); + + emit update(); +} + +void GroupEditor::slotOk() +{ + slotApply(); + + KDialogBase::slotOk(); +} + +void GroupEditor::selectionChanged() +{ + bool issel = groups->currentItem() >= 0; + colorGroupBox->setEnabled(issel); + pricesGroupBox->setEnabled(issel); + dynamicGroupBox->setEnabled(issel); + removeB->setEnabled(issel); +} + +#include "group.moc" diff --git a/atlantikdesigner/designer/group.h b/atlantikdesigner/designer/group.h new file mode 100644 index 0000000..b1ebf99 --- /dev/null +++ b/atlantikdesigner/designer/group.h @@ -0,0 +1,99 @@ +#ifndef GROUP_H +#define GROUP_H + +#include +#include + +#include + +#include + +class KColorButton; +class KLineEdit; +class KListBox; +class KPushButton; + +class QComboBox; +class QListBoxItem; +class QSpinBox; +class QVGroupBox; + +class ConfigEstateGroup +{ + public: + ConfigEstateGroup() { init(); } + ConfigEstateGroup(const QString &name) { setName(name); init(); } + void init() { setHousePrice(0); setGlobalPrice(0); } + + void setHousePrice(int newPrice) { m_housePrice = newPrice; } + int housePrice()const { return m_housePrice; } + void setGlobalPrice(int newGlobalPrice) { m_globalPrice = newGlobalPrice; } + int globalPrice()const { return m_globalPrice; } + const QString &rentMath() { return m_rentMath; } + void setRentMath(const QString &newMath) { m_rentMath = newMath; } + bool dynamicRent()const { return !m_rentMath.isEmpty(); } + void setName(const QString &name) { m_name = name; } + const QString &name() { return m_name; } + + const QColor &fgColor() { return m_fgColor; } + void setFgColor(const QColor &color) { m_fgColor = color; } + const QColor &bgColor() { return m_bgColor; } + void setBgColor(const QColor &color) { m_bgColor = color; } + + private: + QColor m_fgColor; + QColor m_bgColor; + QString m_rentMath; + int m_housePrice; + int m_globalPrice; + QString m_name; +}; +typedef QValueList ConfigEstateGroupList; + +class GroupEditor : public KDialogBase +{ + Q_OBJECT + + public: + GroupEditor(ConfigEstateGroupList *, QWidget *parent=0); + + signals: + void changed(); + void update(); + + protected slots: + virtual void slotOk(); + virtual void slotApply(); + + private slots: + void updateSettings(QListBoxItem *item); + void fgChanged(const QColor &); + void bgChanged(const QColor &); + void housePriceChanged(int); + void globalPriceChanged(int); + void rentMathChanged(const QString &); + void add(); + void remove(); + void selectionChanged(); + + private: + KListBox *groups; + KLineEdit *rentMathEdit; + KColorButton *fgButton; + KColorButton *bgButton; + QWidget *pricesWidget; + QWidget *mathWidget; + QSpinBox *housePrice; + QSpinBox *globalPrice; + QVGroupBox *colorGroupBox; + QVGroupBox *pricesGroupBox; + QVGroupBox *dynamicGroupBox; + KPushButton *removeB; + + ConfigEstateGroupList *list; + ConfigEstateGroupList mylist; + + ConfigEstateGroup *currentGroup(); +}; + +#endif diff --git a/atlantikdesigner/designer/main.cpp b/atlantikdesigner/designer/main.cpp new file mode 100644 index 0000000..b7dee10 --- /dev/null +++ b/atlantikdesigner/designer/main.cpp @@ -0,0 +1,37 @@ +#include +#include +#include +#include + +#include "designer.h" + +int main(int argc, char *argv[]) +{ + KAboutData aboutData( + "atlantikdesigner", + I18N_NOOP("Atlantik Designer"), "1.1.0", + I18N_NOOP("Atlantik gameboard designer"), + KAboutData::License_GPL, + I18N_NOOP("(c) 2002 Jason Katz-Brown"), + 0, + "http://www.unixcode.org/atlantik/" + ); + + aboutData.addAuthor("Jason Katz-Brown", I18N_NOOP("main author"), "jason@katzbrown.com", "http://katzbrown.com/"); + aboutData.addAuthor("Rob Kaper", I18N_NOOP("libatlantikui"), "cap@capsi.com", "http://capsi.com/"); + + KCmdLineArgs::init(argc, argv, &aboutData); + + KApplication kapplication; + + if (kapplication.isRestored()) + RESTORE(AtlanticDesigner) + else + { + AtlanticDesigner *designer = new AtlanticDesigner; + designer->show(); + } + + return kapplication.exec(); +} + diff --git a/atlantikdesigner/pics/Makefile.am b/atlantikdesigner/pics/Makefile.am new file mode 100644 index 0000000..82d6695 --- /dev/null +++ b/atlantikdesigner/pics/Makefile.am @@ -0,0 +1 @@ +KDE_ICON = atlantikdesigner diff --git a/atlantikdesigner/pics/hi16-app-atlantikdesigner.png b/atlantikdesigner/pics/hi16-app-atlantikdesigner.png new file mode 100644 index 0000000..8eb628b Binary files /dev/null and b/atlantikdesigner/pics/hi16-app-atlantikdesigner.png differ diff --git a/atlantikdesigner/pics/hi32-app-atlantikdesigner.png b/atlantikdesigner/pics/hi32-app-atlantikdesigner.png new file mode 100644 index 0000000..881a148 Binary files /dev/null and b/atlantikdesigner/pics/hi32-app-atlantikdesigner.png differ -- cgit v1.2.1