Commit 4139b37b authored by Johannes Bergmeier's avatar Johannes Bergmeier

* Cleanup of symbols handling

* Input in game views now QAction based (except old sift-mode)
* Changed default key-combos (due to conflicts with other keycombos):
- Add marker: Alt + Number -> Shift + Number
- Select value: -removed-
- Hints: Shift -> Control

svn path=/trunk/kdereview/ksudoku/; revision=662533
parent 0ea3d6e6
......@@ -223,7 +223,13 @@ void KSudoku::startGame(const Game& game) {
}
// m_tabs->insertTab(view, "Test");
// m_tabs->showPage(view);
setCentralWidget(view->widget(), true);
QWidget* widget = view->widget();
setCentralWidget(widget, true);
widget->addAction(m_moveUpAct);
widget->addAction(m_moveDownAct);
widget->addAction(m_moveLeftAct);
widget->addAction(m_moveRightAct);
}
void KSudoku::loadGame(const KUrl& Url) {
......@@ -359,21 +365,60 @@ void KSudoku::genMultiple()
}
void KSudoku::selectValue(int value) {
// QWidget* current = m_tabs->currentPage()<
if(ksudokuView* view = dynamic_cast<ksudokuView*>( currentView())) {
view->current_selected_number = value;
} else if (RoxdokuView* view = dynamic_cast<RoxdokuView*>( currentView())) {
view->selected_number = value;
/*} else if (ksudokuCustomView* view = dynamic_cast<ksudokuCustomView*>(current)) {
view->current_selected_number = value;*/
} else return;
KsView* view = currentView();
if(!view) return;
view->selectValue(value);
updateStatusBar();
}
void KSudoku::enterValue(int value) {
KsView* view = currentView();
if(!view) return;
view->enterValue(value);
}
void KSudoku::markValue(int value) {
KsView* view = currentView();
if(!view) return;
view->markValue(value);
}
void KSudoku::moveUp() {
KsView* view = currentView();
if(!view) return;
view->moveUp();
}
void KSudoku::moveDown() {
KsView* view = currentView();
if(!view) return;
view->moveDown();
}
void KSudoku::moveLeft() {
KsView* view = currentView();
if(!view) return;
view->moveLeft();
}
void KSudoku::moveRight() {
KsView* view = currentView();
if(!view) return;
view->moveRight();
}
void KSudoku::clearCell() {
KsView* view = currentView();
if(!view) return;
view->enterValue(0);
}
void KSudoku::KDE3Action(const QString& text, QWidget* object, const char* slot, const QString& name)
......@@ -385,6 +430,8 @@ void KSudoku::KDE3Action(const QString& text, QWidget* object, const char* slot,
void KSudoku::setupActions()
{
KShortcut shortcut;
setAcceptDrops(true);
KStandardAction::openNew(this, SLOT(fileNew()), actionCollection());
......@@ -402,12 +449,6 @@ void KSudoku::setupActions()
KAction* a = new KAction(this);
actionCollection()->addAction(QString("val-select%1").arg(i+1,2,10,QChar('0')), a);
a->setText(i18n("Select %1 (%2)", i+1, QChar('a'+i)));
KShortcut shortcut;
shortcut.setPrimary( Qt::ControlModifier | Qt::Key_A + i );
if(i < 9) {
shortcut.setAlternate( Qt::ControlModifier | Qt::Key_1 + i );
}
a->setShortcut(shortcut);
m_selectValueMapper->setMapping(a, i+1);
connect(a, SIGNAL(triggered(bool)), m_selectValueMapper, SLOT(map()));
addAction(a);
......@@ -429,15 +470,49 @@ void KSudoku::setupActions()
actionCollection()->addAction(QString("val-mark%1").arg(i+1,2,10,QChar('0')), a);
a->setText(i18n("Mark %1 (%2)", i+1, QChar('a'+i)));
shortcut = a->shortcut();
shortcut.setPrimary( Qt::AltModifier | Qt::Key_A + i);
shortcut.setPrimary( Qt::ShiftModifier | Qt::Key_A + i);
if(i < 9) {
shortcut.setAlternate( Qt::AltModifier | Qt::Key_1 + i);
shortcut.setAlternate( Qt::ShiftModifier | Qt::Key_1 + i);
}
a->setShortcut(shortcut);
m_markValueMapper->setMapping(a, i+1);
connect(a, SIGNAL(triggered(bool)), m_markValueMapper, SLOT(map()));
addAction(a);
}
m_moveUpAct = actionCollection()->addAction("move_up");
m_moveUpAct->setText(i18n("Move Up"));
m_moveUpAct->setShortcut(Qt::Key_Up);
connect(m_moveUpAct, SIGNAL(triggered(bool)), SLOT(moveUp()));
// addAction(moveUpAct);
m_moveDownAct = actionCollection()->addAction("move_down");
m_moveDownAct->setText(i18n("Move Down"));
m_moveDownAct->setShortcut(Qt::Key_Down);
connect(m_moveDownAct, SIGNAL(triggered(bool)), SLOT(moveDown()));
// addAction(moveDownAct);
m_moveLeftAct = actionCollection()->addAction("move_left");
m_moveLeftAct->setText(i18n("Move Left"));
m_moveLeftAct->setShortcut(Qt::Key_Left);
connect(m_moveLeftAct, SIGNAL(triggered(bool)), SLOT(moveLeft()));
// addAction(moveLeftAct);
m_moveRightAct = actionCollection()->addAction("move_right");
m_moveRightAct->setText(i18n("Move Right"));
m_moveRightAct->setShortcut(Qt::Key_Right);
connect(m_moveRightAct, SIGNAL(triggered(bool)), SLOT(moveRight()));
// addAction(moveRightAct);
KAction* clearCellAct = new KAction(this);
actionCollection()->addAction("move_clear_cell", clearCellAct);
clearCellAct->setText(i18n("Clear Cell"));
shortcut = clearCellAct->shortcut();
shortcut.setPrimary(Qt::Key_Backspace);
shortcut.setAlternate(Qt::Key_Delete);
clearCellAct->setShortcut(shortcut);
connect(clearCellAct, SIGNAL(triggered(bool)), SLOT(clearCell()));
addAction(clearCellAct);
//History
QAction* undoAct = actionCollection()->addAction("move_undo");
......
......@@ -158,6 +158,11 @@ private slots:
void selectValue(int value);
void enterValue(int value);
void markValue(int value);
void moveUp();
void moveDown();
void moveLeft();
void moveRight();
void clearCell();
void optionsPreferences();
void settingsChanged();
......@@ -201,6 +206,10 @@ private:
QSignalMapper* m_enterValueMapper;
QSignalMapper* m_markValueMapper;
QAction* m_moveUpAct;
QAction* m_moveDownAct;
QAction* m_moveLeftAct;
QAction* m_moveRightAct;
GameVariantCollection* m_gameVariants;
WelcomeScreen* m_welcomeScreen;
......
......@@ -67,10 +67,6 @@ public:
inline void emitFullChange() { emit fullChange(); }
public:
//use this to set order (multiple changes)
void setOrder(int o) { order = o; symbols.setOrder(o); }
int order;
PuzzleState state;
bool hadHelp: 1;
......@@ -80,9 +76,6 @@ public:
KUrl url;
QList<HistoryEvent> history;
int historyPos;
///@todo move this to proper place (or remove this todo)
Symbols symbols;
};
void Game::Private::undo() {
......@@ -141,12 +134,9 @@ Game::Game(Puzzle* puzzle)
m_private->puzzle = puzzle;
m_private->setOrder(puzzle->order());
// m_solver = puzzle->solver();
m_private->hadHelp = false;
m_private->state = PuzzleState(size(), m_private->order);
m_private->state = PuzzleState(size(), m_private->puzzle->order());
m_private->state.reset();
for(int i = 0; i < size(); i++) {
......@@ -207,7 +197,7 @@ bool Game::simpleCheck() const {
int Game::order() const {
if(!m_private) return 0;
return m_private->order;
return m_private->puzzle->order();
}
int Game::index(int x, int y, int z) const {
......@@ -228,10 +218,6 @@ Puzzle* Game::puzzle() const {
if(!m_private) return 0;
return m_private->puzzle;
}
Symbols const* Game::symbols() const {
if(!m_private) return 0;
return &m_private->symbols;
}
bool Game::hasSolver()
{
......@@ -255,7 +241,7 @@ KUrl Game::getUrl() const {
QBitArray Game::highlightValueConnections(int val, bool allValues) const {
if(!m_private) return QBitArray();
if(val <= 0 || val > m_private->order)
if(val <= 0 || val > m_private->puzzle->order())
return QBitArray();
QBitArray array(size());
......@@ -291,7 +277,7 @@ void Game::setGiven(int index, bool given) {
bool Game::setMarker(int index, int val, bool state) {
if(!m_private) return false;
if(val == 0 || val > order())
if(val == 0 || val > m_private->puzzle->order())
return false;
if(m_private->state.given(index))
......@@ -318,7 +304,7 @@ bool Game::setMarker(int index, int val, bool state) {
void Game::setValue(int index, int val) {
if(!m_private) return;
if(val > order()) return;
if(val > m_private->puzzle->order()) return;
if(m_private->state.given(index)) return;
......@@ -392,7 +378,7 @@ bool Game::autoSolve() {
m_private->hadHelp = true;
PuzzleState newState(size(), order());
PuzzleState newState(size(), m_private->puzzle->order());
newState.reset();
for(int i = 0; i < size(); ++i) {
......@@ -458,21 +444,6 @@ const QByteArray Game::allValues() const {
return m_private->state.allValues();
}
QChar Game::value2Char(int value) const {
if(!m_private || value == 0) return QChar('\0');
//return m_private->puzzle->value2Char(value);
return m_private->symbols.symbol(value -1); //-1 due to use of 0 as special value
}
int Game::char2Value(QChar c) const {
if(!m_private) return -1;
//return m_private->puzzle->char2Value(c);
int index = m_private->symbols.symbol2index(c);
return (index < 0) ? index : index+1; //+1 to prevent usage of 0, which is used for other purposes
}
QTime Game::time() const {
if(!m_private) return QTime();
......
......@@ -116,8 +116,6 @@ public:
///@return pointer to current puzzle
Puzzle* puzzle() const;
///@return poiter to symbols used for current puzzle
Symbols const* symbols() const;
/**
* Gets the the interface of the game. Use this if for connecting to signals or
......@@ -180,16 +178,6 @@ public:
*/
const QByteArray allValues() const;
/**
* @see ksudoku::Puzzle::value2Char
*/
QChar value2Char(int value) const;
/**
* @see ksudoku::Puzzle:char2Value
*/
int char2Value(QChar c) const;
/**
* Gives one value in a randomly chosen cell.
*/
......
......@@ -46,11 +46,7 @@ QString SymbolTable::text() const { return m_text; }
// class Symbols
///////////////////////////////////////////////////////////////////////////////
Symbols::Symbols(bool autoType)
: symbolGenerator(0)
, m_autoType(autoType)
, m_symbolType(none)
{
Symbols::Symbols() {
m_possibleTables << new SymbolTable("symbols", i18n("Simple Forms"), QVector<QChar>() << 0x2610 << 0x2606 << 0x2661 << 0x263E);
m_possibleTables << new SymbolTable("dices", i18n("Dices"), QVector<QChar>() << 0x2680 << 0x2681 << 0x2682 << 0x2683 << 0x2684 << 0x2685);
m_possibleTables << new SymbolTable("digits", i18n("Digits"), QVector<QChar>() << '1' << '2' << '3' << '4' << '5' << '6' << '7' << '8' << '9');
......@@ -91,68 +87,4 @@ void Symbols::setEnabledTables(const QStringList& tables) {
emit tablesChanged();
}
QChar Symbols::numberGenerator(int index)
{
///@TODO fix this for internationalization
return QChar(index + '1');
}
QChar Symbols::letterGenerator(int index)
{
///@TODO fix this for internationalization
return QChar(index + 'a');
}
void Symbols::setOrder(uint order)
{
if(Symbols::order() == order)
return;
m_symbolList.resize(order);
if(m_autoType)
autoSetType();
fill();
}
void Symbols::setType(SymbolType symType)
{
if(symType == m_symbolType)
return; //nothing to do
m_symbolType = symType;
switch(m_symbolType){
case numbers:
symbolGenerator = &Symbols::numberGenerator;
break;
case letters:
symbolGenerator = &Symbols::letterGenerator;
break;
default: //none
symbolGenerator = 0;
};
fill(); //(re)fill symbol list
}
void Symbols::autoSetType(){
if(order() < 10)
setType(numbers);
else
setType(letters);
}
void Symbols::fill()
{
if(m_symbolType == none)
autoSetType(); //call setType(<SymbolType>) first
//now just use autoSetTye as best practice
int capacity = m_symbolList.size();
m_symbolList.clear();
for( int i=0; i < capacity ; ++i){
m_symbolList.push_back((this->*symbolGenerator)(i));
}
}
}
......@@ -28,9 +28,6 @@
namespace ksudoku {
typedef QVector<QChar> SymbolList;
enum SymbolType { numbers, letters, none};
struct SymbolTable {
public:
SymbolTable(const QString& name, const QString& text, const QVector<QChar>& symbols);
......@@ -46,59 +43,14 @@ private:
};
/**
* Provide (in a consistend way) the symbols for puzzles.
* Provdes lookup to and from symbols used in the user interface
* (eventually this class must provide in more symbols then the western
* alphanumeric characters)
* Provides the symbols for puzzles.
*/
class Symbols : public QObject {
Q_OBJECT
//default will copy memberpointer which will be ok => no need
// ///prevent copy constructor
// Symbols(Symbols const& other);
// ///prevent assignment
// Symbols& operator=(Symbols const& other);
public:
Symbols(bool autoType = true);
Symbols();
~Symbols();
///set type of symbols (numbers or chars)
void setType(SymbolType symType);
///choses symbol type according to order (order < 10 => numbers, else chars)
void autoSetType();
///return symbol at index @a index
QChar const& symbol(int index) const { return m_symbolList[index]; }
///overloaded index operator, same as @ref symbol(int index)
QChar const& operator[](int index) const { return symbol(index); }
///convert symbol to index number
///@return -1 if s is not a valid symbol, else returns index number
///@TODO check this for efficiency (if only used for lookup at user input current implementation is usable)
int symbol2index(QChar const& s) const {
SymbolList::const_iterator iter = m_symbolList.begin();
SymbolList::const_iterator end = m_symbolList.end ();
int i = 0;
while(iter != end)
if(*iter == s) return i;
else { ++i; ++iter; }
return -1; //return error
}
//setters
///set new order (number of elements in list)
void setOrder(uint order);
//getters
///return current order (number of elements in list)
uint order() const { return m_symbolList.size(); }
///return current symbol type
SymbolType const symbolType() const { return m_symbolType; }
///return reference to current symbol list
///(list may change while using the result)
SymbolList const& symbolList() const { return m_symbolList; }
QList<SymbolTable*> possibleTables() const;
QStringList enabledTables() const;
......@@ -136,25 +88,6 @@ signals:
void tablesChanged();
private:
///symbol generator, generates numbers
QChar numberGenerator(int index);
///symbol generator, generates letters
QChar letterGenerator(int index);
///function pointer to the current symbol generator
QChar (Symbols::*symbolGenerator)(int index);
///(re)fill the symbol list
void fill();
///if true, then autoSetType will be called when order changes
bool m_autoType;
///holds the symbols
SymbolList m_symbolList;
///current symbol type
SymbolType m_symbolType;
QList<SymbolTable*> m_possibleTables;
QList<SymbolTable*> m_enabledTables;
};
......
......@@ -299,22 +299,58 @@ void ksudokuView::setGame(const ksudoku::Game& game) {
//printf("DONE\n");
}
}
#include <QtDebug>
namespace ksudoku {
void ksudokuView::selectValue(int value) {
current_selected_number = value;
}
void ksudokuView::enterValue(int value) {
if(!m_game.given(m_currentCell)) {
m_game.flipMarker(value, m_currentCell);
m_game.setValue(m_currentCell, value);
}
}
void ksudokuView::markValue(int value) {
if(!m_game.given(m_currentCell)) {
m_game.flipMarker(value, m_currentCell);
m_game.flipMarker(m_currentCell, value);
}
}
void ksudokuView::moveUp() {
Graph* g = m_game.puzzle()->solver()->g;
int x = g->cellPosX(m_currentCell);
int y = g->cellPosY(m_currentCell);
if(--y < 0) y = g->sizeY()-1;
btn_enter(x,y);
}
void ksudokuView::moveDown() {
Graph* g = m_game.puzzle()->solver()->g;
int x = g->cellPosX(m_currentCell);
int y = g->cellPosY(m_currentCell);
if(++y >= g->sizeY()) y = 0;
btn_enter(x,y);
}
void ksudokuView::moveLeft() {
Graph* g = m_game.puzzle()->solver()->g;
int x = g->cellPosX(m_currentCell);
int y = g->cellPosY(m_currentCell);
if(--x < 0) x = g->sizeX()-1;
btn_enter(x,y);
}
void ksudokuView::moveRight() {
Graph* g = m_game.puzzle()->solver()->g;
int x = g->cellPosX(m_currentCell);
int y = g->cellPosY(m_currentCell);
if(++x >= g->sizeX()) x = 0;
btn_enter(x,y);
}
void ksudokuView::beginHighlight(int val)
{
if( ! m_game.hasSolver()) return;
......
......@@ -91,6 +91,10 @@ public:
void selectValue(int value);
void enterValue(int value);
void markValue(int value);
void moveUp();
void moveDown();
void moveLeft();
void moveRight();
protected:
void resizeEvent(QResizeEvent *);
......
......@@ -55,4 +55,17 @@ void KsView::enterValue(int value) {
void KsView::markValue(int value) {
}
void KsView::moveUp() {
}
void KsView::moveDown() {
}
void KsView::moveLeft() {
}
void KsView::moveRight() {
}
}
......@@ -76,6 +76,10 @@ public:
virtual void selectValue(int value);
virtual void enterValue(int value);
virtual void markValue(int value);
virtual void moveUp();
virtual void moveDown();
virtual void moveLeft();
virtual void moveRight();
protected:
///pointer to external Game
......
......@@ -143,75 +143,15 @@ void QSudokuButton::exitEvent (QEvent *)
void QSudokuButton::keyPressEvent ( QKeyEvent * e )
{
if(!isConnected()) return;
if(m_ksView.game().value(m_x,m_y) == 0) return;
if(e->modifiers() & Qt::ShiftModifier)
if(e->modifiers() & Qt::ControlModifier)
emit beginHighlight(m_ksView.game().value(m_x,m_y));
e->ignore(); //pass on
}
void QSudokuButton::keyReleaseEvent ( QKeyEvent *e )
{
if(!isConnected()) return;
for(;;){ //hack to avoid goto's to one lable
//think about it and change your view on goto's !!
//(the loop never loops, but he, no goto's)
emit finishHighlight();
int key = e->key();
switch(key){
//process move (arrow) keys