You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdeedu/kvoctrain/kvoctrain/kvoctraintable.cpp

607 lines
16 KiB

/***************************************************************************
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 <tqpainter.h>
#include <tqstyle.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, TQWidget *parent, const char *name)
: TQTable(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 = TQPixmap(KGlobal::iconLoader()->loadIcon("ok", KIcon::Small));
m_pixInactive = TQPixmap(KGlobal::iconLoader()->loadIcon("no", KIcon::Small));
delayTimer = new TQTimer(this);
connect(delayTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(menuTriggerTimeout()));
TQHeader *header = horizontalHeader();
connect(header, TQT_SIGNAL(pressed(int)), this, TQT_SLOT(headerPressEvent(int)));
connect(header, TQT_SIGNAL(released(int)), this, TQT_SLOT(headerReleaseEvent(int)));
connect(this, TQT_SIGNAL(currentChanged(int, int)), this, TQT_SLOT(slotCurrentChanged(int, int)));
}
void KVocTrainTable::setCurrentItem(int row)
{
setCurrentRow(row, currentColumn());
}
/*
TQWidget* KVocTrainTable::beginEdit(int row, int col, bool replace)
{
if (KApplication::dcopClient()->isApplicationRegistered("kxkb"))
{
if (m_doc)
{
TQString id = (col == KV_COL_ORG) ? m_doc->getOriginalIdent() : m_doc->getIdent(col - KV_EXTRA_COLS);
if (langs)
{
TQString kbLayout(langs->keyboardLayout(langs->indexShortId(id)));
kdDebug() << "Keyboard Layout: " << kbLayout << endl;
if (!kbLayout.isEmpty())
{
TQByteArray data, replyData;
TQCString replyType;
TQDataStream arg(data, IO_WriteOnly);
arg << kbLayout;
if (!KApplication::dcopClient()->call("kxkb", "kxkb", "setLayout(TQString)", data, replyType, replyData))
{
kdDebug() << "kxkb dcop error: beginEdit()" << endl;
}
}
}
}
}
return TQTable::beginEdit(row, col, replace);
}
void KVocTrainTable::endEdit(int row, int col, bool accept, bool replace)
{
TQTable::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;
}
TQApplication::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());
TQApplication::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)
{
TQTable::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 = TQMAX(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 = TQMAX(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 = TQMIN(current_row, TQMAX(0, numRows()-1));
current_col = TQMIN(current_col, TQMAX(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(TQMAX(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, TQTableItem::OnTyping, rows);
}
else {
defaultItem = d;
defaultItem->setDoc(rows);
}
//gradecols = gc;
}
void KVocTrainTable::menuTriggerTimeout()
{
delayTimer->stop();
if (triggerSect == -1)
return;
int mt = triggerSect;
triggerSect = -1;
TQHeader *header = horizontalHeader();
int x = leftMargin();
for (int i = 0; i < mt; ++i)
x += header->sectionSize(i);
TQPoint mpos = mapToGlobal(TQPoint(x, topMargin()));
if (mt != KV_COL_MARK)
emit rightButtonClicked(mt, mpos.x(), mpos.y());
TQMouseEvent me(TQEvent::MouseButtonRelease, TQPoint(0, 0), Qt::LeftButton, Qt::LeftButton);
TQApplication::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 TQFont & font)
{
TQTable::setFont(font);
horizontalHeader()->setFont(KGlobalSettings::generalFont());
for (unsigned i = 0; i < (unsigned) numRows(); ++i)
setRowHeight(i, fontMetrics().lineSpacing());
}
int cellAlignment(const TQString & text)
{
bool num;
bool ok1 = false;
bool ok2 = false;
text.toInt(&ok1);
if (!ok1)
text.toDouble(&ok2);
num = ok1 || ok2;
return ( num ? TQt::AlignRight : TQt::AlignAuto ) | TQt::AlignVCenter;
}
void KVocTrainTable::paintCell(TQPainter * p, int row, int col, const TQRect & cr, bool selected, const TQColorGroup &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( TQColorGroup::Highlight ) : cg.brush( TQColorGroup::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);
TQColor 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
{
TQString less_str;
if (m_doc != 0 && expr->getLesson() != 0)
less_str = m_doc->getLessonDescr(expr->getLesson());
p->drawText( 3, fontpos, w, p->fontMetrics().lineSpacing(), TQt::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
{
TQString s = expr->getOriginal();
p->drawText(3, fontpos, w - 6, p->fontMetrics().lineSpacing(), cellAlignment(s), s);
}
break;
default: // translation x
TQString s = expr->getTranslation(col - KV_COL_ORG);
p->drawText(3, fontpos, w - 6, p->fontMetrics().lineSpacing(), cellAlignment(s), s);
break;
}
p->restore();
}
TQPen pen( p->pen() );
int gridColor = style().styleHint( TQStyle::SH_Table_GridLineColor, this );
if (gridColor != -1) {
const TQPalette &pal = palette();
if (cg != colorGroup()
&& cg != pal.disabled()
&& cg != pal.inactive())
p->setPen(cg.mid());
else
p->setPen((TQRgb)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, TQTableItem * /*item*/)
{
// ignore item!
updateContents(row, col);
}
TQTableItem * KVocTrainTable::item(int row, int col) const
{
if (defaultItem)
defaultItem->setPosition(row, col);
return defaultItem;
}
void KVocTrainTable::keyPressEvent(TQKeyEvent * e)
{
delayTimer->stop();
switch(e->key())
{
case Key_Right: {
int topCell = rowAt(0);
int lastRowVisible = TQMIN(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:
TQTable::keyPressEvent(e);
break;
case Key_Left: {
TQTable::keyPressEvent(e);
int topCell = rowAt(0);
int lastRowVisible = TQMIN(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
TQTable::keyPressEvent(e);
emit forwardKeyPressEvent(e);
break;
case Key_Minus:
case Key_Plus:
case Key_Tab:
case Key_Backtab: // fallthrough
emit forwardKeyPressEvent(e);
break;
default:
TQTable::keyPressEvent(e);
break;
}
}
void KVocTrainTable::keyReleaseEvent(TQKeyEvent * e)
{
delayTimer->stop();
switch(e->key())
{
case Key_Shift:
case Key_Alt:
case Key_Control: // fallthrough
TQTable::keyPressEvent(e);
emit forwardKeyReleaseEvent(e);
break;
}
}
void KVocTrainTable::contentsMousePressEvent(TQMouseEvent * e)
{
delayTimer->stop();
int cc = columnAt(e->x());
int cr = rowAt(e->y());
int co = currentColumn();
TQTable::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 = TQMIN(numRows(), rowAt(contentsHeight()));
if (update_org)
for (int i = topCell; i <= lastRowVisible; i++)
updateCell(i, KV_COL_ORG);
}
if(e->button() == Qt::LeftButton)
setCurrentCell(cr, cc);
}
void KVocTrainTable::contentsMouseDoubleClickEvent(TQMouseEvent * e)
{
delayTimer->stop();
TQTable::contentsMouseDoubleClickEvent(e);
}
void KVocTrainTable::activateNextCell()
{
int currRow = currentRow();
int currCol = currentColumn();
TQTableSelection 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)
{
TQString id = (col == KV_COL_ORG) ? m_doc->getOriginalIdent() : m_doc->getIdent(col - KV_EXTRA_COLS);
if (langs)
{
TQString kbLayout(langs->keyboardLayout(langs->indexShortId(id)));
//kdDebug() << "Keyboard Layout: " << kbLayout << endl;
if (!kbLayout.isEmpty())
{
TQByteArray data, replyData;
TQCString replyType;
TQDataStream arg(data, IO_WriteOnly);
arg << kbLayout;
if (!KApplication::dcopClient()->call("kxkb", "kxkb", "setLayout(TQString)", data, replyType, replyData))
{
kdDebug() << "kxkb dcop error: beginEdit()" << endl;
}
}
}
}
}
}
#include "kvoctraintable.moc"