summaryrefslogtreecommitdiffstats
path: root/kvoctrain/kvoctrain/kvoctraintable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kvoctrain/kvoctrain/kvoctraintable.cpp')
-rw-r--r--kvoctrain/kvoctrain/kvoctraintable.cpp606
1 files changed, 606 insertions, 0 deletions
diff --git a/kvoctrain/kvoctrain/kvoctraintable.cpp b/kvoctrain/kvoctrain/kvoctraintable.cpp
new file mode 100644
index 00000000..98e64c13
--- /dev/null
+++ b/kvoctrain/kvoctrain/kvoctraintable.cpp
@@ -0,0 +1,606 @@
+/***************************************************************************
+
+ table for kvoctrain
+
+ -----------------------------------------------------------------------
+
+ begin : Tue Jan 4 19:04:53 PST 2005
+
+ copyright :(C) 2005 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 <qpainter.h>
+#include <qstyle.h>
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <dcopclient.h>
+#include <klocale.h>
+#include <kglobalsettings.h>
+#include <kstandarddirs.h>
+#include <kiconloader.h>
+
+#include "kvoctraintable.h"
+#include "kv_resource.h"
+#include "prefs.h"
+
+KVocTrainTable::KVocTrainTable(kvoctrainDoc *doc, const LangSet *ls, QWidget *parent, const char *name)
+ : QTable(parent, name), langs(ls)
+{
+ m_doc = doc;
+ defaultItem = 0;
+ setNumCols(m_doc->numLangs());
+ setNumRows(m_doc->numEntries());
+
+ setLeftMargin(0);
+ setSelectionMode(MultiRow);
+ setColumnMovingEnabled(false);
+ setRowMovingEnabled(false);
+ setSorting(false);
+
+ setDoc(m_doc);
+
+ triggerSect = -1;
+
+ m_pixInQuery = QPixmap(KGlobal::iconLoader()->loadIcon("ok", KIcon::Small));
+ m_pixInactive = QPixmap(KGlobal::iconLoader()->loadIcon("no", KIcon::Small));
+
+ delayTimer = new QTimer(this);
+ connect(delayTimer, SIGNAL(timeout()), this, SLOT(menuTriggerTimeout()));
+
+ QHeader *header = horizontalHeader();
+ connect(header, SIGNAL(pressed(int)), this, SLOT(headerPressEvent(int)));
+ connect(header, SIGNAL(released(int)), this, SLOT(headerReleaseEvent(int)));
+
+ connect(this, SIGNAL(currentChanged(int, int)), this, SLOT(slotCurrentChanged(int, int)));
+}
+
+
+void KVocTrainTable::setCurrentItem(int row)
+{
+ setCurrentRow(row, currentColumn());
+}
+/*
+QWidget* KVocTrainTable::beginEdit(int row, int col, bool replace)
+{
+ if (KApplication::dcopClient()->isApplicationRegistered("kxkb"))
+ {
+ if (m_doc)
+ {
+ QString id = (col == KV_COL_ORG) ? m_doc->getOriginalIdent() : m_doc->getIdent(col - KV_EXTRA_COLS);
+
+ if (langs)
+ {
+ QString kbLayout(langs->keyboardLayout(langs->indexShortId(id)));
+ kdDebug() << "Keyboard Layout: " << kbLayout << endl;
+ if (!kbLayout.isEmpty())
+ {
+ QByteArray data, replyData;
+ QCString replyType;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << kbLayout;
+
+ if (!KApplication::dcopClient()->call("kxkb", "kxkb", "setLayout(QString)", data, replyType, replyData))
+ {
+ kdDebug() << "kxkb dcop error: beginEdit()" << endl;
+ }
+ }
+ }
+ }
+ }
+ return QTable::beginEdit(row, col, replace);
+}
+
+void KVocTrainTable::endEdit(int row, int col, bool accept, bool replace)
+{
+ QTable::endEdit(row, col, accept, replace);
+}
+*/
+void KVocTrainTable::sortByColumn(int header, bool alpha) {
+ if (header == KV_COL_MARK)
+ return;
+
+ if (header >= numRows()) {
+ kdError() << "header >= numRows()\n";
+ return;
+ }
+
+ if (m_doc && !m_doc->isAllowedSorting()) {
+ KMessageBox::information(this, i18n("Sorting is currently turned off for this document.\n"
+ "\nUse the document properties dialog to turn sorting on."), kapp->makeStdCaption(""));
+ return;
+ }
+
+ QApplication::setOverrideCursor(waitCursor);
+
+ clearSelection();
+
+ bool sortdir = false;
+ if (m_doc) {
+ if (header >= KV_COL_ORG)
+ sortdir = m_doc->sort(header-KV_EXTRA_COLS);
+ else
+ if (alpha)
+ sortdir = m_doc->sortByLesson_alpha();
+ else
+ sortdir = m_doc->sortByLesson_index();
+ }
+ horizontalHeader()->setSortIndicator(header, sortdir);
+ repaintContents();
+ m_doc->setModified();
+ emit currentChanged(currentRow(), currentColumn());
+ QApplication::restoreOverrideCursor();
+}
+
+void KVocTrainTable::sortByColumn_alpha(int header)
+{
+ sortByColumn(header, true);
+}
+
+
+void KVocTrainTable::slotSelectionChanged()
+{
+ emit currentChanged(currentRow(), currentColumn());
+}
+
+
+void KVocTrainTable::sortByColumn_index(int header)
+{
+ sortByColumn(header, false);
+}
+
+void KVocTrainTable::setCurrentRow(int row, int col)
+{
+ QTable::setCurrentCell(row, col);
+}
+
+void KVocTrainTable::updateContents(int row, int col)
+{
+ int current_row = row;
+ if (current_row < 0)
+ current_row = currentRow();
+ int current_col = col;
+ if (current_col < 0)
+ current_col = currentColumn();
+ int ncols, nrows;
+ if (m_doc) {
+ nrows = m_doc->numEntries();
+ ncols = QMAX(1, m_doc->numLangs())+KV_EXTRA_COLS;
+ }
+ else {
+ nrows = 0;
+ ncols = 1+KV_EXTRA_COLS;
+ }
+ if (nrows != numRows()) {
+ // remember number of new rows (typically one)
+ unsigned int new_rows = QMAX(0, nrows - numRows());
+ // adjust number of rows
+ setNumRows(nrows);
+ // adjust row heights for added rows
+ for (int i=nrows-new_rows; i<nrows; ++i)
+ setRowHeight(i, fontMetrics().lineSpacing());
+ }
+ if (ncols != numCols())
+ setNumCols(ncols);
+ current_row = QMIN(current_row, QMAX(0, numRows()-1));
+ current_col = QMIN(current_col, QMAX(0, numCols()-1));
+ bool b = signalsBlocked();
+ blockSignals(true);
+ setCurrentRow(current_row, current_col);
+ blockSignals(b);
+ viewport()->update();
+ emit currentChanged(current_row, current_col);
+}
+
+kvoctrainExpr *KVocTrainTable::getRow(int row)
+{
+ if (m_doc)
+ return m_doc->getEntry(row);
+ else
+ return 0;
+}
+
+void KVocTrainTable::setDoc(kvoctrainDoc * rows)
+{
+ if (defaultItem)
+ endEdit(defaultItem->row(), defaultItem->col(), true, false);
+
+ KVocTrainTableItem *d = defaultItem;
+ defaultItem = 0;
+
+ if (rows) {
+ m_doc = rows;
+ setNumRows(rows->numEntries());
+ setNumCols(QMAX(1+KV_EXTRA_COLS, m_doc->numLangs()+KV_EXTRA_COLS));
+ setCurrentRow(0, 0);
+ }
+ else {
+ setNumRows(0);
+ setNumCols(1+KV_EXTRA_COLS);
+ m_doc = 0;
+ }
+
+ if (d == 0) {
+ defaultItem = new KVocTrainTableItem(this, QTableItem::OnTyping, rows);
+ }
+ else {
+ defaultItem = d;
+ defaultItem->setDoc(rows);
+ }
+ //gradecols = gc;
+}
+
+void KVocTrainTable::menuTriggerTimeout()
+{
+ delayTimer->stop();
+ if (triggerSect == -1)
+ return;
+
+ int mt = triggerSect;
+ triggerSect = -1;
+
+ QHeader *header = horizontalHeader();
+ int x = leftMargin();
+ for (int i = 0; i < mt; ++i)
+ x += header->sectionSize(i);
+ QPoint mpos = mapToGlobal(QPoint(x, topMargin()));
+
+ if (mt != KV_COL_MARK)
+ emit rightButtonClicked(mt, mpos.x(), mpos.y());
+
+ QMouseEvent me(QEvent::MouseButtonRelease, QPoint(0, 0), QMouseEvent::LeftButton, QMouseEvent::LeftButton);
+ QApplication::sendEvent(header, &me);
+}
+
+void KVocTrainTable::headerReleaseEvent(int /*sec*/)
+{
+ delayTimer->stop();
+ if(triggerSect == -1) { // long enough pressed for popup menu
+ return;
+ }
+ int mt = triggerSect;
+ triggerSect = -1;
+ emit selected(mt);
+}
+
+void KVocTrainTable::headerPressEvent(int sec)
+{
+ triggerSect = sec;
+ delayTimer->stop();
+ delayTimer->start(500, true);
+}
+
+void KVocTrainTable::setFont(const QFont & font)
+{
+ QTable::setFont(font);
+ horizontalHeader()->setFont(KGlobalSettings::generalFont());
+ for (unsigned i = 0; i < (unsigned) numRows(); ++i)
+ setRowHeight(i, fontMetrics().lineSpacing());
+}
+
+int cellAlignment(const QString & text)
+{
+ bool num;
+ bool ok1 = false;
+ bool ok2 = false;
+ text.toInt(&ok1);
+ if (!ok1)
+ text.toDouble(&ok2);
+ num = ok1 || ok2;
+
+ return ( num ? Qt::AlignRight : Qt::AlignAuto ) | Qt::AlignVCenter;
+}
+
+
+void KVocTrainTable::paintCell(QPainter * p, int row, int col, const QRect & cr, bool selected, const QColorGroup &cg)
+{
+ if (cr.width() == 0 || cr.height() == 0)
+ return;
+
+ if (selected && row == currentRow() && col == currentColumn() && (hasFocus() || viewport()->hasFocus()))
+ selected = false;
+
+ int w = cr.width();
+ int h = cr.height();
+ int x2 = w - 1;
+ int y2 = h - 1;
+
+ p->fillRect( 0, 0, w, h, selected ? cg.brush( QColorGroup::Highlight ) : cg.brush( QColorGroup::Base ) );
+
+ kvoctrainExpr *expr = getRow(row);
+ if (expr)
+ {
+ p->save();
+ //cell->paint(p, col, w, selected, m_doc, numCols() == KV_EXTRA_COLS+2 ? KV_COL_TRANS : currentColumn(), gradecols);
+
+ QColor color = KV_NORM_COLOR;
+ int current_col = numCols() == KV_EXTRA_COLS+2 ? KV_COL_TRANS : currentColumn();
+
+ if (Prefs::useGradeCol())
+ {
+ if (col > KV_COL_ORG)
+ {
+ color = Prefs::gradeCol(0);
+ if (expr->getQueryCount(col - KV_EXTRA_COLS, false) != 0)
+ {
+ switch (expr->getGrade(col-KV_EXTRA_COLS, false))
+ {
+ case KV_NORM_GRADE: color = Prefs::gradeCol(0); break;
+ case KV_LEV1_GRADE: color = Prefs::gradeCol(1); break;
+ case KV_LEV2_GRADE: color = Prefs::gradeCol(2); break;
+ case KV_LEV3_GRADE: color = Prefs::gradeCol(3); break;
+ case KV_LEV4_GRADE: color = Prefs::gradeCol(4); break;
+ case KV_LEV5_GRADE: color = Prefs::gradeCol(5); break;
+ case KV_LEV6_GRADE: color = Prefs::gradeCol(6); break;
+ case KV_LEV7_GRADE: color = Prefs::gradeCol(7); break;
+ default : color = Prefs::gradeCol(1);
+ }
+ }
+ }
+ else if ( col == KV_COL_ORG )
+ {
+ color = Prefs::gradeCol(0);
+ if (expr->numTranslations() != 0 && current_col > KV_COL_ORG )
+ {
+ if (expr->getQueryCount(current_col - KV_EXTRA_COLS, true) != 0 )
+ {
+ switch (expr->getGrade(current_col - KV_EXTRA_COLS, true))
+ {
+ case KV_LEV1_GRADE: color = Prefs::gradeCol(1); break;
+ case KV_LEV2_GRADE: color = Prefs::gradeCol(2); break;
+ case KV_LEV3_GRADE: color = Prefs::gradeCol(3); break;
+ case KV_LEV4_GRADE: color = Prefs::gradeCol(4); break;
+ case KV_LEV5_GRADE: color = Prefs::gradeCol(5); break;
+ case KV_LEV6_GRADE: color = Prefs::gradeCol(6); break;
+ case KV_LEV7_GRADE: color = Prefs::gradeCol(7); break;
+ default : color = Prefs::gradeCol(1);
+ }
+ }
+ }
+ }
+ }
+
+ if (selected)
+ p->setPen (cg.highlightedText());
+ else
+ p->setPen (color);
+
+ int fontpos = (p->fontMetrics().lineSpacing() - p->fontMetrics().lineSpacing()) / 2;
+
+ switch (col)
+ {
+ case KV_COL_LESS: // lesson
+ {
+ QString less_str;
+ if (m_doc != 0 && expr->getLesson() != 0)
+ less_str = m_doc->getLessonDescr(expr->getLesson());
+ p->drawText( 3, fontpos, w, p->fontMetrics().lineSpacing(), Qt::AlignLeft, less_str);
+ }
+ break;
+
+ case KV_COL_MARK: // mark
+ {
+ if (!expr->isActive())
+ {
+ p->drawPixmap((w - m_pixInactive.width()) / 2,
+ (p->fontMetrics().lineSpacing() - m_pixInactive.height())/2, m_pixInactive);
+ }
+ else if (expr->isInQuery() )
+ {
+ p->drawPixmap((w - m_pixInQuery.width()) / 2,
+ (p->fontMetrics().lineSpacing() - m_pixInQuery.height())/2, m_pixInQuery);
+ }
+ }
+ break;
+
+ case KV_COL_ORG: // original
+ {
+ QString s = expr->getOriginal();
+ p->drawText(3, fontpos, w - 6, p->fontMetrics().lineSpacing(), cellAlignment(s), s);
+ }
+ break;
+
+ default: // translation x
+ QString s = expr->getTranslation(col - KV_COL_ORG);
+ p->drawText(3, fontpos, w - 6, p->fontMetrics().lineSpacing(), cellAlignment(s), s);
+ break;
+ }
+ p->restore();
+ }
+
+ QPen pen( p->pen() );
+ int gridColor = style().styleHint( QStyle::SH_Table_GridLineColor, this );
+ if (gridColor != -1) {
+ const QPalette &pal = palette();
+ if (cg != colorGroup()
+ && cg != pal.disabled()
+ && cg != pal.inactive())
+ p->setPen(cg.mid());
+ else
+ p->setPen((QRgb)gridColor);
+ } else {
+ p->setPen(cg.mid());
+ }
+ p->drawLine( x2, 0, x2, y2 );
+ p->drawLine( 0, y2, x2, y2 );
+ p->setPen( pen );
+}
+
+void KVocTrainTable::setItem(int row, int col, QTableItem * /*item*/)
+{
+ // ignore item!
+ updateContents(row, col);
+}
+
+QTableItem * KVocTrainTable::item(int row, int col) const
+{
+ if (defaultItem)
+ defaultItem->setPosition(row, col);
+ return defaultItem;
+}
+
+void KVocTrainTable::keyPressEvent(QKeyEvent * e)
+{
+ delayTimer->stop();
+ switch(e->key())
+ {
+ case Key_Right: {
+ int topCell = rowAt(0);
+ int lastRowVisible = QMIN(numRows(), rowAt(contentsHeight()));
+ if (numCols() > 2)
+ for (int i = topCell; i <= lastRowVisible; i++)
+ updateCell(i, KV_COL_ORG);
+ } // fallthrough
+ case Key_Up:
+ case Key_Down:
+ case Key_Next:
+ case Key_Prior:
+ QTable::keyPressEvent(e);
+ break;
+
+ case Key_Left: {
+ QTable::keyPressEvent(e);
+ int topCell = rowAt(0);
+ int lastRowVisible = QMIN(numRows(), rowAt(contentsHeight()));
+ if (numCols() > 2)
+ for (int i = topCell; i <= lastRowVisible; i++)
+ updateCell(i, KV_COL_ORG);
+ }
+ break;
+
+ case Key_Shift:
+ case Key_Alt:
+ case Key_Control: // fallthrough
+ QTable::keyPressEvent(e);
+ emit forwardKeyPressEvent(e);
+ break;
+
+ case Key_Minus:
+ case Key_Plus:
+ case Key_Tab:
+ case Key_Backtab: // fallthrough
+ emit forwardKeyPressEvent(e);
+ break;
+
+ default:
+ QTable::keyPressEvent(e);
+ break;
+ }
+}
+
+void KVocTrainTable::keyReleaseEvent(QKeyEvent * e)
+{
+ delayTimer->stop();
+ switch(e->key())
+ {
+ case Key_Shift:
+ case Key_Alt:
+ case Key_Control: // fallthrough
+ QTable::keyPressEvent(e);
+ emit forwardKeyReleaseEvent(e);
+ break;
+ }
+}
+
+void KVocTrainTable::contentsMousePressEvent(QMouseEvent * e)
+{
+ delayTimer->stop();
+ int cc = columnAt(e->x());
+ int cr = rowAt(e->y());
+ int co = currentColumn();
+
+ QTable::contentsMousePressEvent(e);
+
+ if(cc >= KV_EXTRA_COLS) {
+ // update color of original when column changes and more than 1 translation
+ bool update_org = false;
+ if (cc != co && numCols() > 2)
+ update_org = true;
+
+ int topCell = rowAt(0);
+ int lastRowVisible = QMIN(numRows(), rowAt(contentsHeight()));
+ if (update_org)
+ for (int i = topCell; i <= lastRowVisible; i++)
+ updateCell(i, KV_COL_ORG);
+ }
+ if(e->button() == LeftButton)
+ setCurrentCell(cr, cc);
+}
+
+void KVocTrainTable::contentsMouseDoubleClickEvent(QMouseEvent * e)
+{
+ delayTimer->stop();
+ QTable::contentsMouseDoubleClickEvent(e);
+}
+
+void KVocTrainTable::activateNextCell()
+{
+ int currRow = currentRow();
+ int currCol = currentColumn();
+
+ QTableSelection currentSel = selection(0);
+
+ int tr = currentSel.topRow();
+ int br = currentSel.bottomRow();
+ int lc = currentSel.leftCol();
+ int rc = currentSel.rightCol();
+
+ if (currCol == rc)
+ {
+ if (currRow < br)
+ setCurrentCell(currRow + 1, lc);
+ else
+ setCurrentCell(tr, lc);
+ }
+ else
+ setCurrentCell(currRow, currCol + 1);
+
+}
+
+void KVocTrainTable::slotCurrentChanged(int row, int col)
+{
+ Q_UNUSED(row);
+ if (KApplication::dcopClient()->isApplicationRegistered("kxkb"))
+ {
+ if (m_doc)
+ {
+ QString id = (col == KV_COL_ORG) ? m_doc->getOriginalIdent() : m_doc->getIdent(col - KV_EXTRA_COLS);
+
+ if (langs)
+ {
+ QString kbLayout(langs->keyboardLayout(langs->indexShortId(id)));
+ //kdDebug() << "Keyboard Layout: " << kbLayout << endl;
+ if (!kbLayout.isEmpty())
+ {
+ QByteArray data, replyData;
+ QCString replyType;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << kbLayout;
+
+ if (!KApplication::dcopClient()->call("kxkb", "kxkb", "setLayout(QString)", data, replyType, replyData))
+ {
+ kdDebug() << "kxkb dcop error: beginEdit()" << endl;
+ }
+ }
+ }
+ }
+ }
+
+}
+
+#include "kvoctraintable.moc"