diff options
Diffstat (limited to 'kwordquiz/src/kwordquizview.cpp')
-rw-r--r-- | kwordquiz/src/kwordquizview.cpp | 1083 |
1 files changed, 1083 insertions, 0 deletions
diff --git a/kwordquiz/src/kwordquizview.cpp b/kwordquiz/src/kwordquizview.cpp new file mode 100644 index 00000000..69e2046b --- /dev/null +++ b/kwordquiz/src/kwordquizview.cpp @@ -0,0 +1,1083 @@ +/*************************************************************************** + kwordquizview.cpp - description + ------------------- + begin : Wed Jul 24 20:12:30 PDT 2002 + copyright : (C) 2002 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +// include files for Qt +#include <qpainter.h> +#include <qtable.h> +#include <qclipboard.h> +#include <qlineedit.h> + +// include files for KDE +#include <klocale.h> //i18n +#include <kmessagebox.h> // always useful +#include <krandomsequence.h> +#include <kglobalsettings.h> +#include <knotifyclient.h> + +// application specific includes +#include "kwordquizview.h" +#include "kwordquizdoc.h" +#include "kwordquiz.h" +#include "dlgsort.h" +#include "prefs.h" +#include "dlgrc.h" +#include "dlgspecchar.h" + +QValueList<WQUndo> *KWordQuizView::m_undoList = 0L; + +KWQTableItem::KWQTableItem(QTable* table, EditType et, const QString & text) : QTableItem(table, et, text) +{} + +int KWQTableItem::alignment() const +{ + bool num; + bool ok1 = false; + bool ok2 = false; + (void)text().toInt(&ok1); + if (!ok1) + (void)text().toDouble(&ok2); + num = ok1 || ok2; + + return (num ? Qt::AlignRight : Qt::AlignAuto) | Qt::AlignVCenter; +} + +KWordQuizView::KWordQuizView(QWidget *parent, const char *name) : QTable(parent, name) +{ + if(!m_undoList) + m_undoList = new QValueList<WQUndo>(); + + setNumCols(2); + setNumRows(50); + setColumnWidth(1, 250); + setColumnWidth(0, 250); + setSelectionMode(QTable::Single); + horizontalHeader()->setLabel(0, i18n("Column 1")); + horizontalHeader()->setLabel(1, i18n("Column 2")); + setMinimumSize(0, 0); //This seems to improve resizing of main window + dlgSpecChar = 0; +} + +KWordQuizView::~KWordQuizView() +{ +} + +KWordQuizDoc *KWordQuizView::getDocument() const +{ + KWordQuizApp *theApp=(KWordQuizApp *) parentWidget(); + return theApp->getDocument(); +} + +void KWordQuizView::print(KPrinter *pPrinter) +{ + QPainter painter; + + //type 0 Vocabulary list + //type 1 Vocabulary exam + //type 2 Flashcards + int type = pPrinter->option("kde-kwordquiz-type").toInt(); + + //I think working with screen resolution is enough for our purposes + int res = pPrinter->resolution(); + int pad = 2; + int marg = res; + int card_marg = res / 2; + int card_width = 5 * res; + int card_height = 3 * res; + int card_text_marg = res /5; + int card_line_top = 30; + + if (type == 2) + pPrinter->setOrientation(KPrinter::Landscape); + + painter.begin(pPrinter); + + int pageNum = 1; + + int cw0 = verticalHeader()->width(); + int cw1 = columnWidth(0); + int cw2 = columnWidth(1); + int cw3 = 0; + + + + if (type == 1) + cw3 = 50; + + int gridWidth = cw0 + cw1 + cw2 + cw3; + int lPos = marg; + int tPos = marg + horizontalHeader()->height(); + + QRect w = painter.window(); + + doNewPage(painter, res, type); + + if (type == 2) + { + tPos = card_marg; + for (int rc = 0; rc < numRows(); ++rc) + { + + //draw rectangle 2 cards wide + painter.drawRect(card_marg, tPos, 2 * card_width, card_height); + //divide into 2 cards with line + painter.drawLine(card_marg + card_width, tPos, card_marg + card_width, tPos + card_height); + //draw line inside card + painter.drawLine(card_marg + card_text_marg, tPos + card_line_top, + card_marg + card_width - card_text_marg, tPos + card_line_top); + painter.drawLine(card_marg + card_width + card_text_marg, tPos + card_line_top, + card_marg + card_width + card_width - card_text_marg, tPos + card_line_top); + //draw headers + painter.setFont(KGlobalSettings::generalFont()); + painter.drawText(card_marg + card_text_marg, tPos, card_width, card_line_top, AlignAuto | AlignVCenter, horizontalHeader()->label(0)); + painter.drawText(card_marg + card_width + card_text_marg, tPos, card_width, card_line_top, AlignAuto | AlignVCenter, horizontalHeader()->label(1)); + //draw text + painter.setFont(font()); + painter.drawText(card_marg + card_text_marg, tPos + card_line_top, card_width - (2 * card_text_marg), card_height - card_line_top, AlignHCenter | AlignVCenter | WordBreak, text(rc, 0)); + painter.drawText(card_marg + card_width + card_text_marg, tPos + card_line_top, card_width - (2 * card_text_marg), card_height - card_line_top, AlignHCenter | AlignVCenter | WordBreak, text(rc, 1)); + + tPos = tPos + card_height + card_line_top; + + if (tPos + card_height + card_line_top > w.height() - card_marg) + { + doEndOfPage(painter, tPos, pageNum++, res, type); + tPos = card_marg; + pPrinter->newPage(); + doNewPage(painter, res, type); + } + } + + } + else + { + + for (int rc = 0; rc < numRows(); ++rc) + { + painter.drawLine(lPos, tPos, lPos + gridWidth, tPos); + painter.setFont(KGlobalSettings::generalFont()); + + painter.drawText(lPos, tPos, cw0 - pad, rowHeight(rc), AlignRight | AlignVCenter, QString::number(rc + 1)); + + painter.setFont(font()); + painter.drawText(lPos + cw0 + pad, tPos, cw1, rowHeight(rc), AlignAuto | AlignVCenter | WordBreak, text(rc, 0)); + + if (type == 0) + painter.drawText(lPos + cw0 + cw1 + pad, tPos, cw2, rowHeight(rc), AlignAuto | AlignVCenter | WordBreak, text(rc, 1)); + + tPos = tPos + rowHeight(rc); + + if (tPos + rowHeight(rc + 1) > w.height() - marg) + { + doEndOfPage(painter, tPos, pageNum++, res, type); + tPos = marg + horizontalHeader()->height(); + pPrinter->newPage(); + doNewPage(painter, res, type); + } + } + } + doEndOfPage(painter, tPos, pageNum++, res, type); + painter.end(); +} + +void KWordQuizView::doNewPage( QPainter & painter, int res, int type ) +{ + int cw0 = verticalHeader()->width(); + int cw1 = columnWidth(0); + int cw2 = columnWidth(1); + int cw3 = 0; + int marg = res; + int card_marg = res / 2; + int pad = 2; + + if (type == 1) + cw3 = 50; + + QRect w = painter.window(); + + painter.setFont(KGlobalSettings::generalFont()); + + if (type == 2) + { + painter.drawText(card_marg, card_marg - 20, i18n("KWordQuiz - %1").arg(getDocument()->URL().fileName())); + return; + } + painter.drawLine(marg, marg, marg + cw0 + cw1 + cw2 + cw3, marg); + + painter.drawText(marg, marg - 20, i18n("KWordQuiz - %1").arg(getDocument()->URL().fileName())); + + if (type == 1) + { + QString score = i18n("Name:_____________________________ Date:__________"); + QRect r = painter.boundingRect(0, 0, 0, 0, AlignAuto, score); + painter.drawText(w.width() - r.width() - marg, marg - 20, score); + } + + painter.drawText(marg, marg, cw0, horizontalHeader()->height(), AlignRight | AlignVCenter, ""); + + painter.drawText(marg + cw0 + pad, marg, cw1, horizontalHeader()->height(), AlignAuto | AlignVCenter, horizontalHeader()->label(0)); + painter.drawText(marg + cw0 + cw1 + pad, marg, cw2, horizontalHeader()->height(), AlignAuto | AlignVCenter, horizontalHeader()->label(1)); + + if (type == 1) + painter.drawText(marg + cw0 + cw1 + cw2 + pad, marg, cw3, horizontalHeader()->height(), AlignAuto | AlignVCenter, i18n("Score")); + +} + +void KWordQuizView::doEndOfPage( QPainter & painter, int vPos, int pageNum, int res, int type ) +{ + int marg = res; + painter.setFont(KGlobalSettings::generalFont()); + QRect w = painter.window(); + QRect r = painter.boundingRect(0, 0, 0, 0, AlignAuto, QString::number(pageNum)); + painter.drawText((w.width()/2) - (r.width()/2), w.height() - marg + 20, QString::number(pageNum)); + + if (type == 2) + return; + + int cw0 = verticalHeader()->width(); + int cw1 = columnWidth(0); + int cw2 = columnWidth(1); + int cw3 = 0; + + if (type == 1) + cw3 = 50; + + //Last horizontal line + painter.drawLine(marg, vPos, marg + cw0 + cw1 + cw2 + cw3, vPos); + //Four vertical lines + painter.drawLine(marg, marg, marg, vPos); + painter.drawLine(marg + cw0, marg, marg + cw0, vPos); + painter.drawLine(marg + cw0 + cw1, marg, marg + cw0 + cw1, vPos); + painter.drawLine(marg + cw0 + cw1 + cw2, marg, marg + cw0 + cw1 + cw2, vPos); + + if (type == 1) + painter.drawLine(marg + cw0 + cw1 + cw2 + cw3, marg, marg + cw0 + cw1 + cw2 + cw3, vPos); + +} + + + +/*! + \fn KWordQuizView::gridIsEmpty() + */ +bool KWordQuizView::gridIsEmpty() +{ + for(int i = 0; i < numRows(); i++){ + for(int j = 0; j < 2; j++){ + if(!text(i, j).isEmpty()){ + return false; + } + } + } + return true; +} + +QWidget * KWordQuizView::beginEdit( int row, int col, bool replace ) +{ + m_currentText = text(row, col); + cellEditor = QTable::beginEdit(row, col, replace); + if (cellEditor) + cellEditor->installEventFilter(this); + return cellEditor; +} + +void KWordQuizView::endEdit( int row, int col, bool accept, bool replace ) +{ + // this code gets called after enter and arrow keys, now we + // only process if editing really has been done + + if (cellWidget(row, col) != 0) //if edited the cellWidget still exists + { + if (((QLineEdit *) cellWidget(row, col))->text() != m_currentText) + addUndo(i18n("&Undo Entry")); + QTable::endEdit(row, col, accept, replace); //this will destroy the cellWidget + if (!text(row, col).isEmpty()) + { + QTableItem* itm; + itm = item(row, col); + itm->setWordWrap(true); + adjustRow(row); + getDocument() -> setModified(true); + if (Prefs::enableBlanks()) + if (!checkForBlank(text(row, col), true)) + KNotifyClient::event(winId(), "SyntaxError", i18n("There is an error with the Fill-in-the-blank brackets")); + } + } +} + +void KWordQuizView::adjustRow( int row ) +{ + // we want to make the row high enough to display content, but + // if the user already made it even higher we keep that height + int rh = rowHeight(row); + QTable::adjustRow(row); + if (rh > rowHeight(row)) + setRowHeight(row, rh); +} + +void KWordQuizView::saveCurrentSelection(bool clear = true) +{ + + m_currentRow = currentRow(); + m_currentCol = currentColumn(); + + if (numSelections() > 0) + { + m_currentSel = selection(0); + if (clear) + clearSelection(); + } + else + { + QTableSelection* ts; + ts = new QTableSelection(m_currentRow, m_currentCol, m_currentRow, m_currentCol); + m_currentSel = *ts; + } +} + +void KWordQuizView::doEditUndo( ) +{ + if (isEditing()) + { + if (((QLineEdit *) cellWidget(currentRow(), currentColumn()))->isUndoAvailable()) + ((QLineEdit *) cellWidget(currentRow(), currentColumn()))->undo(); + } + else + { + WQUndo undo; + if (m_undoList->count() > 0) + { + setUpdatesEnabled(false); + undo = m_undoList->first(); + setFont(undo.font()); + verticalHeader()->setMinimumWidth(undo.colWidth0()); + setColumnWidth(0, undo.colWidth1()); + setColumnWidth(1, undo.colWidth2()); + setNumRows(0); + setNumRows(undo.numRows()); + setCurrentCell(undo.currentRow(), undo.currentCol()); + addSelection(undo.selection()); + + QString s; + int i = 0; + KWqlDataItemList dataList = undo.list(); + KWqlDataItemList::ConstIterator end(dataList.end()); + for(KWqlDataItemList::ConstIterator dataIt = dataList.begin(); dataIt != end; ++dataIt) + { + s = (*dataIt).frontText(); + if (!s.isEmpty()) + setText(i, 0, s); //calling setText only when there actually is text helps with sorting + s = (*dataIt).backText(); + if (!s.isEmpty()) + setText(i, 1, s); + setRowHeight(i, (*dataIt).rowHeight()); + i++; + } + + m_undoList->remove(m_undoList->begin()); + setUpdatesEnabled(true); + } + + if (m_undoList->count() > 0) + { + undo = m_undoList->first(); + emit undoChange(undo.text(), true); + } + else + emit undoChange(i18n("Cannot &Undo"), false); + } +} + +void KWordQuizView::doEditCut( ) +{ + if (isEditing()) + { + ((QLineEdit *) cellWidget(currentRow(), currentColumn()))->cut(); + } + else + { + addUndo(i18n("&Undo Cut")); + doEditCopy(); + saveCurrentSelection(); + for (int r = m_currentSel.topRow(); r <= m_currentSel.bottomRow(); ++r) + for(int c = m_currentSel.leftCol(); c <= m_currentSel.rightCol(); ++c) + clearCell(r, c); + } + getDocument()->setModified(true); +} + +void KWordQuizView::doEditCopy( ) +{ + bool mod = getDocument()->isModified(); + if (isEditing()) + { + ((QLineEdit *) cellWidget(currentRow(), currentColumn()))->copy(); + } + else + { + saveCurrentSelection(false); + QString s; + for (int r = m_currentSel.topRow(); r <= m_currentSel.bottomRow(); ++r) + { + for (int c = m_currentSel.leftCol(); c <= m_currentSel.rightCol(); ++c) + s = s + text(r, c) + "\t"; + s = s + "\n"; + } + kapp->clipboard()->setText(s); + } + getDocument()->setModified(mod); +} + +void KWordQuizView::doEditPaste( ) +{ + if (isEditing()) + { + ((QLineEdit *) cellWidget(currentRow(), currentColumn()))->paste(); + } + else + { + addUndo(i18n("&Undo Paste")); + saveCurrentSelection(); + int tr = m_currentSel.topRow(); + int br = m_currentSel.bottomRow(); + int lc = m_currentSel.leftCol(); + int rc = m_currentSel.rightCol(); + + if (lc == rc && tr == br) //one cell selected + { + QString s = kapp->clipboard()->text(); + QStringList sl; + sl = QStringList::split("\n", s); + + uint r = numRows() - tr; + + if (sl.count() > r) //do we need to add rows? + { + setNumRows(numRows() + (sl.count() - r)); + br = numRows(); + } + else + br= br + sl.count() - 1; + + if (lc == 0) //left col? + if (sl[0].find("\t") < ((int) sl[0].length() - 1)) + rc = 1; //expand to second column; + + uint i = 0; + int ar = tr; + QStringList sr; + while(i < sl.count() && br <= numRows() ) + { + int ac = lc; + + sr = QStringList::split("\t", sl[i]); + int c = 0; + while (ac <= rc) + { + setText(ar, ac, sr[c]); + ac++; + c++; + } + ar++; + i++; + } + + + } + else + { + QString s = kapp->clipboard()->text(); + QStringList sl; + sl = QStringList::split("\n", s); + uint i = 0; + int ar = tr; + QStringList sr; + while(i < sl.count() && ar <= br ) + { + int ac = lc; + + sr = QStringList::split("\t", sl[i]); + int c = 0; + while (ac <= rc) + { + setText(ar, ac, sr[c]); + ac++; + c++; + } + ar++; + i++; + } + } + + //restore selection + addSelection(QTableSelection(tr, lc, br, rc)); + setCurrentCell(m_currentRow, m_currentCol); + } + getDocument()->setModified(true); +} + +void KWordQuizView::doEditClear( ) +{ + if (isEditing()) + { + ((QLineEdit *) cellWidget(currentRow(), currentColumn()))->clear(); + } + else + { + addUndo(i18n("&Undo Clear")); + saveCurrentSelection(false); + for (int r = m_currentSel.topRow(); r <= m_currentSel.bottomRow(); ++r) + for(int c = m_currentSel.leftCol(); c <= m_currentSel.rightCol(); ++c) + clearCell(r, c); + } + getDocument()->setModified(true); +} + +void KWordQuizView::doEditInsert( ) +{ + addUndo(i18n("&Undo Insert")); + setUpdatesEnabled(false); + saveCurrentSelection(); + insertRows(m_currentSel.topRow(), m_currentSel.bottomRow() - m_currentSel.topRow() + 1); + + addSelection(QTableSelection(m_currentSel.topRow(), m_currentSel.leftCol(), m_currentSel.bottomRow(), m_currentSel.rightCol())); + setCurrentCell(m_currentRow, m_currentCol); + setUpdatesEnabled(true); + repaintContents(); + getDocument()->setModified(true); +} + +void KWordQuizView::doEditDelete( ) +{ + addUndo(i18n("&Undo Delete")); + //retrieve current selection + saveCurrentSelection(); + + int tr = m_currentSel.topRow(); + int br = m_currentSel.bottomRow(); + + if (tr == 0 && br == numRows() - 1) + br--; //leave one row if all rows are selected + + for (int r = br; r >= tr; --r) + removeRow(r); + + if (br > numRows()) + br = numRows(); //adjust for new numRows + + //restore selection as much as possible + addSelection(QTableSelection(tr, m_currentSel.leftCol(), br, m_currentSel.rightCol())); + setCurrentCell(m_currentRow, m_currentCol); + getDocument()->setModified(true); +} + +const char delim_start = '['; +const char delim_end = ']'; + + +bool KWordQuizView::checkForBlank( const QString & s, bool blank ) +{ + if (!blank) + return true; + + bool result = false; + int openCount = 0; + int closeCount = 0; + QMemArray<int> openPos(0); + QMemArray<int> closePos(0); + + for (uint i = 0; i<= s.length(); ++i) + { + if (s[i] == delim_start) + { + openCount++; + openPos.resize(openCount); + openPos[openCount] = i; + } + + if (s[i] == delim_end) + { + closeCount++; + closePos.resize(closeCount); + closePos[closeCount] = i; + } + } + + if (openCount == 0 && closeCount == 0) + return true; + + if (openCount > 0 && closeCount > 0) + if (openPos.size() == closePos.size()) + for (uint i = 0; i <= openPos.size(); ++i) + result = (openPos[i] < closePos[i]); + + return result; +} + +void KWordQuizView::doEditMarkBlank( ) +{ + if (isEditing()) + { + addUndo(i18n("&Undo Mark Blank")); + QLineEdit * l = (QLineEdit *) cellWidget(currentRow(), currentColumn()); + if (l->text().length() > 0) + { + QString s = l->text(); + int cp = l->cursorPosition(); + if (!l->hasSelectedText()) + { + if (!s[cp].isSpace() && !s[cp - 1].isSpace()) + { + l->cursorWordBackward(false); + int cp1 = l->cursorPosition(); + l->cursorWordForward(false); + if (l->cursorPosition() != (int) s.length()) + { while(l->text()[l->cursorPosition()].isSpace()) + l->cursorBackward(false, 1); + } + int cp2 = l->cursorPosition(); + if (cp2 == (int) s.length()) + l->setSelection(cp1, cp2 - cp1); + else + l->setSelection(cp1, cp2 - cp1 - 1); + + } + else + return; + } + + + if (l->hasSelectedText()) + { + QString st = l->selectedText(); + int len = st.length(); + st = st.prepend(delim_start); + st = st.append(delim_end); + int ss = l->selectionStart(); + s = s.replace(ss, len, st); + l->setText(s); + l->setSelection(ss, st.length()); + } + } + } +} + +void KWordQuizView::doEditUnmarkBlank( ) +{ + addUndo(i18n("&Undo Unmark Blank")); + QString s; + + if (isEditing()) + { + QLineEdit * l = (QLineEdit *) cellWidget(currentRow(), currentColumn()); + + if (l->hasSelectedText()) + { + QString ls = l->text(); + s = l->selectedText(); + int len = s.length(); + s.remove(delim_start); + s.remove(delim_end); + int ss = l->selectionStart(); + ls = ls.replace(ss, len, s); + l->setText(ls); + l->setSelection(ss, s.length()); + } + else + { + if (l->text().length() > 0) + { + s = l->text(); + int cs = l->cursorPosition(); + + int fr = s.findRev(delim_start, cs); + if (fr > 0) + { + s = s.replace(fr, 1, ""); + cs--; + } + int ff = s.find(delim_end, cs); + if (ff > 0) + s = s.replace(ff, 1, ""); + + l->setText(s); + l->setCursorPosition(cs); + } + } + } + else + { + saveCurrentSelection(false); + for (int r = m_currentSel.topRow(); r <= m_currentSel.bottomRow(); ++r) + for(int c = m_currentSel.leftCol(); c <= m_currentSel.rightCol(); ++c) + { + s = text(r, c); + s = s.remove(delim_start); + s = s.remove(delim_end); + setText(r, c, s); + } + } +} + +bool KWordQuizView::checkSyntax(bool all, bool blanks) +{ + int errorCount = 0; + int r1, r2, c1 ,c2; + + if (all) + { + r1 = 0; + r2 = numRows() - 1; + c1 = 0; + c2 = 1; + } + else + { + saveCurrentSelection(false); + r1 = m_currentSel.topRow(); + r2 = m_currentSel.bottomRow(); + c1 = m_currentSel.leftCol(); + c2 = m_currentSel.rightCol(); + } + + for (int r = r1; r <= r2; ++r) + for(int c = c1 ; c <= c2 ; ++c ) + { + QString s = text(r, c); + if (s.length() > 0) + for (uint i = 0; i <= s.length(); ++i) + if (s[i] == delim_start || s[i] == delim_end) + if (!checkForBlank(s, blanks)) + errorCount++; + } + return (errorCount == 0); +} + +void KWordQuizView::doVocabSort( ) +{ + saveCurrentSelection(); + DlgSort* dlg; + dlg = new DlgSort(this, "dlg_sort", true); + dlg->setLanguage(1, horizontalHeader()->label(0)); + dlg->setLanguage(2, horizontalHeader()->label(1)); + dlg->disableResize(); + if (dlg->exec() == KDialogBase::Accepted) + { + addUndo(i18n("&Undo Sort")); + if (dlg->base()) + sortColumn(0, dlg->ascending(), true); + else + sortColumn(1, dlg->ascending(), true); + getDocument()->setModified(true); + } + //restore selection + addSelection(QTableSelection(m_currentSel.topRow(), m_currentSel.leftCol(), m_currentSel.bottomRow(), m_currentSel.rightCol())); + setCurrentCell(m_currentRow, m_currentCol); +} + +void KWordQuizView::doVocabShuffle( ) +{ + //@todo handle empty rows + addUndo(i18n("&Undo Shuffle")); + saveCurrentSelection(); + KRandomSequence* rs; + rs = new KRandomSequence(); + int count = numRows(); + setUpdatesEnabled(false); + while (count > 0) + { + swapRows(count-1, rs->getLong(count)); + count--; + } + //restore selection + addSelection(QTableSelection(m_currentSel.topRow(), m_currentSel.leftCol(), m_currentSel.bottomRow(), m_currentSel.rightCol())); + setCurrentCell(m_currentRow, m_currentCol); + setUpdatesEnabled(true); + repaintContents(); + getDocument()->setModified(true); +} + +void KWordQuizView::doVocabRC( ) +{ + saveCurrentSelection(); + DlgRC* dlg; + dlg = new DlgRC(this, "dlg_rc", true); + //dlg->setInitialSize(QSize(225, 230), true); + dlg->setNumRows(numRows()); + dlg->setRowHeight(rowHeight(m_currentRow)); + dlg->setColWidth(columnWidth(m_currentCol)); + dlg->disableResize(); + if (dlg->exec() == KDialogBase::Accepted) + { + if (dlg->numRows() < 1) + setNumRows(1); + else + setNumRows(dlg->numRows()); + for (int i = m_currentSel.topRow(); i <= m_currentSel.bottomRow(); ++i) + setRowHeight(i, dlg->rowHeight()); + for (int i = m_currentSel.leftCol(); i <= m_currentSel.rightCol(); ++i) + setColumnWidth(i, dlg->colWidth()); + getDocument()->setModified(true); + } + addSelection(QTableSelection(m_currentSel.topRow(), m_currentSel.leftCol(), m_currentSel.bottomRow(), m_currentSel.rightCol())); + setCurrentCell(m_currentRow, m_currentCol); +} + +void KWordQuizView::doVocabSpecChar( ) +{ + QString f = font().family(); + QChar c=' '; + if (dlgSpecChar==0) + { + dlgSpecChar = new DlgSpecChar( this, "insert special char", f, c, false ); + connect( dlgSpecChar, SIGNAL(insertChar(QChar)), this, SLOT(slotSpecChar(QChar))); + connect( dlgSpecChar, SIGNAL( finished() ), this, SLOT( slotDlgSpecCharClosed() ) ); + } + dlgSpecChar->show(); +} + +void KWordQuizView::slotDlgSpecCharClosed( ) +{ + if ( dlgSpecChar ) + { + disconnect( dlgSpecChar, SIGNAL(insertChar(QChar)), this, SLOT(slotSpecChar(QChar))); + disconnect( dlgSpecChar, SIGNAL( finished() ), this, SLOT( slotDlgSpecCharClosed() ) ); + dlgSpecChar->deleteLater(); + dlgSpecChar = 0L; + } +} + +void KWordQuizView::slotSpecChar(const QChar & c) +{ + if (isEditing()) + { + QLineEdit * l = (QLineEdit *) cellWidget(currentRow(), currentColumn()); + if (l->hasSelectedText()) + { + QString ls = l->text(); + QString s = l->selectedText(); + int len = s.length(); + int ss = l->selectionStart(); + ls = ls.replace(ss, len, c); + l->setText(ls); + l->setSelection(ss, 1); + } + else + { + QString s = l->text(); + int i = l->cursorPosition(); + s.insert(i, c); + l->setText(s); + l->setCursorPosition(i + 1); + } + } + else + { + editCell(currentRow(), currentColumn(), true); + ((QLineEdit *) cellWidget(currentRow(), currentColumn()))->setText(c); + ((QLineEdit *) cellWidget(currentRow(), currentColumn()))->setCursorPosition(1); + } +} + +void KWordQuizView::activateNextCell( ) +{ + saveCurrentSelection(false); + int tr = m_currentSel.topRow(); + int br = m_currentSel.bottomRow(); + int lc = m_currentSel.leftCol(); + int rc = m_currentSel.rightCol(); + + if (lc == rc && tr == br) //one cell selected + { + clearSelection(); + switch(Prefs::enterMove()) + { + case 0: + if (m_currentRow == (numRows() - 1)) + setNumRows(numRows() + 1); + setCurrentCell(m_currentRow + 1, m_currentCol); + break; + case 1: + if (m_currentCol == 0) + setCurrentCell(m_currentRow, m_currentCol + 1); + else + { + if (m_currentRow == (numRows() - 1)) + setNumRows(numRows() + 1); + setCurrentCell(m_currentRow + 1, m_currentCol - 1); + } + break; + case 2: + setCurrentCell(m_currentRow, m_currentCol); + break; + } + } + else //a larger selection, move within it + { + //addSelection(QTableSelection(m_currentSel.topRow(), m_currentSel.leftCol(), m_currentSel.bottomRow(), m_currentSel.rightCol())); + switch(Prefs::enterMove()) + { + case 0: + if (m_currentRow == br) + { + if (m_currentCol < rc) + setCurrentCell(tr, rc); + else + setCurrentCell(tr, lc); + } + else + if (m_currentRow < br) + setCurrentCell(m_currentRow + 1, m_currentCol); + break; + case 1: + if (m_currentCol == rc) + { + if (m_currentRow < br) + setCurrentCell(m_currentRow + 1, lc); + else + setCurrentCell(tr, lc); + } + else + setCurrentCell(m_currentRow, m_currentCol + 1); + break; + case 2: + setCurrentCell(m_currentRow, m_currentCol); + break; + } + } +} + +void KWordQuizView::addUndo( const QString & caption ) +{ + while (m_undoList->count() > 10) + { + m_undoList->remove(m_undoList->begin()); + } + + WQUndo* undo = new WQUndo(); + undo->setText(caption); + undo->setFont(font()); + undo->setColWidth0(verticalHeader()->width()); + undo->setColWidth1(columnWidth(0)); + undo->setColWidth2(columnWidth(1)); + undo->setNumRows(numRows()); + undo->setCurrentRow(currentRow()); + undo->setCurrentCol(currentColumn()); + undo->setSelection(selection(0)); + + KWqlDataItemList list; + for(int i = 0; i < numRows(); i++) + { + KWqlDataItem item(text(i, 0), text(i, 1), rowHeight(i)); + list.append(item); + } + + undo->setList(list); + + m_undoList->prepend(*undo); + + getDocument()->setModified(true); + + emit undoChange(caption, true); +} + +void KWordQuizView::setFont( const QFont & font) +{ + QTable::setFont(font); + horizontalHeader()->setFont(KGlobalSettings::generalFont()); + verticalHeader()->setFont(KGlobalSettings::generalFont()); + for (int i = 0; i < numRows(); ++i) + adjustRow(i); //setRowHeight(i, fontMetrics().lineSpacing() ); +} + +void KWordQuizView::paintCell( QPainter * p, int row, int col, const QRect & cr, bool selected, const QColorGroup & cg ) +{ + QColorGroup g (cg); + + if (Prefs::enableBlanks()) + if (!checkForBlank(text(row, col), true)) + g.setColor(QColorGroup::Text, Qt::red); + + QTable::paintCell (p, row, col, cr, selected, g ); +} + +void KWordQuizView::keyPressEvent( QKeyEvent * e) +{ + /*if (isEditing()) + if (e->key() == Key_Tab) + { + endEdit(currentRow(), currentColumn(), true, true); + activateNextCell(); + return; + } + else + return; + */ + if (e->key() == Key_Tab) + { + activateNextCell(); + return; + } + QTable::keyPressEvent(e); +} + +void KWordQuizView::slotCheckedAnswer( int i ) +{ + if (i == -1) + { + clearSelection(); + addSelection(QTableSelection(m_currentSel.topRow(), m_currentSel.leftCol(), m_currentSel.bottomRow(), m_currentSel.rightCol())); + setCurrentCell(m_currentRow, m_currentCol); + } + else + { + clearSelection(); + setCurrentCell(i, 0); + selectRow(i); + } +} + +bool KWordQuizView::eventFilter( QObject * o, QEvent * e ) +{ + if (o == cellEditor) + { + if ( e->type() == QEvent::KeyPress ) + { + QKeyEvent *k = (QKeyEvent *)e; + if (k->key() == Key_Tab) + { + endEdit(currentRow(), currentColumn(), true, true); + activateNextCell(); + return true; + } + } + } + return QTable::eventFilter(o, e); +} + +void KWordQuizView::setText(int row, int col, const QString & text) +{ + QTableItem *itm = item(row, col); + if (itm) { + itm->setText(text); + itm->updateEditor(row, col); + updateCell(row, col); + } else { + KWQTableItem *i = new KWQTableItem(this, QTableItem::OnTyping, text); + setItem(row, col, i); + } +} + +#include "kwordquizview.moc" |