/*************************************************************************** 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 #include #include #include #include #include #include #include #include #include #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(TDEGlobal::iconLoader()->loadIcon("ok", TDEIcon::Small)); m_pixInactive = TQPixmap(TDEGlobal::iconLoader()->loadIcon("no", TDEIcon::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 (TDEApplication::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 (!TDEApplication::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; iupdate(); 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(TDEGlobalSettings::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 (TDEApplication::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 (!TDEApplication::dcopClient()->call("kxkb", "kxkb", "setLayout(TQString)", data, replyType, replyData)) { kdDebug() << "kxkb dcop error: beginEdit()" << endl; } } } } } } #include "kvoctraintable.moc"