30 #include <keduvoctranslation.h>
31 #include <keduvocexpression.h>
33 #include <QHeaderView>
35 #include <QResizeEvent>
39 #include <KApplication>
40 #include <KNotification>
41 #include <KComponentData>
42 #include <KGlobalSettings>
44 #include <KActionCollection>
45 #include <KToggleAction>
47 #include <KMessageBox>
49 #include <sonnet/backgroundchecker.h>
52 using namespace Editor;
56 m_spellChecker(0), m_spellDialog(0)
58 installEventFilter(
this);
62 horizontalHeader()->setResizeMode(QHeaderView::Interactive);
63 setEditTriggers(QAbstractItemView::AnyKeyPressed | QAbstractItemView::EditKeyPressed | QAbstractItemView::DoubleClicked);
65 setSortingEnabled(
true);
66 setTabKeyNavigation(
true);
69 setItemDelegate(m_vocabularyDelegate);
71 setFrameStyle(QFrame::NoFrame);
72 setAlternatingRowColors(
true);
75 setContextMenuPolicy(Qt::ActionsContextMenu);
76 horizontalHeader()->setContextMenuPolicy(Qt::ActionsContextMenu);
82 setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
84 m_appendEntryAction =
new KAction(
this);
85 parent->actionCollection()->addAction(
"edit_append", m_appendEntryAction);
86 m_appendEntryAction->setIcon(KIcon(
"list-add-card"));
87 m_appendEntryAction->setText(i18n(
"&Add New Entry"));
88 connect(m_appendEntryAction, SIGNAL(triggered(
bool)), SLOT(
appendEntry()));
89 m_appendEntryAction->setShortcut(QKeySequence(Qt::Key_Insert));
90 m_appendEntryAction->setWhatsThis(i18n(
"Append a new row to the vocabulary"));
91 m_appendEntryAction->setToolTip(m_appendEntryAction->whatsThis());
92 m_appendEntryAction->setStatusTip(m_appendEntryAction->whatsThis());
93 addAction(m_appendEntryAction);
95 m_deleteEntriesAction =
new KAction(
this);
96 parent->actionCollection()->addAction(
"edit_remove_selected_area", m_deleteEntriesAction);
97 m_deleteEntriesAction->setIcon(KIcon(
"list-remove-card"));
98 m_deleteEntriesAction->setText(i18n(
"&Delete Entry"));
100 m_deleteEntriesAction->setShortcut(QKeySequence(Qt::Key_Delete));
101 m_deleteEntriesAction->setWhatsThis(i18n(
"Delete the selected rows"));
102 m_deleteEntriesAction->setToolTip(m_deleteEntriesAction->whatsThis());
103 m_deleteEntriesAction->setStatusTip(m_deleteEntriesAction->whatsThis());
104 addAction(m_deleteEntriesAction);
106 QAction* separator =
new QAction(
this);
107 separator->setSeparator(
true);
108 addAction(separator);
110 m_copyAction = KStandardAction::copy(
this, SLOT(
slotEditCopy()), parent->actionCollection());
111 m_copyAction->setWhatsThis(i18n(
"Copy"));
112 m_copyAction->setToolTip(m_copyAction->whatsThis());
113 m_copyAction->setStatusTip(m_copyAction->whatsThis());
114 addAction(m_copyAction);
116 m_cutAction = KStandardAction::cut(
this, SLOT(
slotCutEntry()), parent->actionCollection());
117 m_cutAction->setWhatsThis(i18n(
"Cut"));
118 m_cutAction->setToolTip(m_cutAction->whatsThis());
119 m_cutAction->setStatusTip(m_cutAction->whatsThis());
120 addAction(m_cutAction);
122 m_pasteAction = KStandardAction::paste(
this, SLOT(
slotEditPaste()), parent->actionCollection());
123 m_pasteAction->setWhatsThis(i18n(
"Paste"));
124 m_pasteAction->setToolTip(m_pasteAction->whatsThis());
125 m_pasteAction->setStatusTip(m_pasteAction->whatsThis());
126 addAction(m_pasteAction);
128 m_selectAllAction = KStandardAction::selectAll(
this, SLOT(selectAll()), parent->actionCollection());
129 m_selectAllAction->setWhatsThis(i18n(
"Select all rows"));
130 m_selectAllAction->setToolTip(m_selectAllAction->whatsThis());
131 m_selectAllAction->setStatusTip(m_selectAllAction->whatsThis());
133 m_clearSelectionAction = KStandardAction::deselect(
this, SLOT(clearSelection()), parent->actionCollection());
134 m_clearSelectionAction->setWhatsThis(i18n(
"Deselect all rows"));
135 m_clearSelectionAction->setToolTip(m_clearSelectionAction->whatsThis());
136 m_clearSelectionAction->setStatusTip(m_clearSelectionAction->whatsThis());
139 KAction *vocabularyColumnsDialogAction =
new KAction(
this);
140 parent->actionCollection()->addAction(
"show_vocabulary_columns_dialog", vocabularyColumnsDialogAction);
141 vocabularyColumnsDialogAction->setIcon(KIcon(
"view-file-columns"));
142 vocabularyColumnsDialogAction->setText(i18n(
"Vocabulary Columns..."));
143 vocabularyColumnsDialogAction->setWhatsThis(i18n(
"Toggle display of individual vocabulary columns"));
144 vocabularyColumnsDialogAction->setToolTip(vocabularyColumnsDialogAction->whatsThis());
145 vocabularyColumnsDialogAction->setStatusTip(vocabularyColumnsDialogAction->whatsThis());
146 horizontalHeader()->addAction(vocabularyColumnsDialogAction);
147 addAction(vocabularyColumnsDialogAction);
153 QTableView::setModel(model);
155 connect(selectionModel(), SIGNAL(currentChanged(
const QModelIndex &,
const QModelIndex &)),
156 SLOT(slotCurrentChanged(
const QModelIndex &,
const QModelIndex &)));
157 connect(selectionModel(), SIGNAL(selectionChanged(
const QItemSelection&,
const QItemSelection&)),
158 SLOT(slotSelectionChanged(
const QItemSelection&,
const QItemSelection&)));
159 slotSelectionChanged(QItemSelection(), QItemSelection());
162 void VocabularyView::slotCurrentChanged(
const QModelIndex & current,
const QModelIndex & previous)
165 KEduVocExpression* entry = 0;
166 if ( current.isValid() ) {
177 QList<int> visibleColumns;
183 KConfig parleyConfig(
"parleyrc");
184 KConfigGroup documentGroup( &parleyConfig,
"Document " + m_doc->url().url() );
185 QByteArray state = documentGroup.readEntry(
"VocabularyColumns", QByteArray() );
187 if (!horizontalHeader()->restoreState(state)) {
188 resizeColumnsToContents();
192 for(
int i = 0; i < model()->columnCount(QModelIndex()); i++) {
193 if (i < visibleColumns.size()) {
194 setColumnHidden(i, !visibleColumns.value(i));
197 setColumnHidden(i,
true);
210 QList<int> visibleList;
211 for (
int i = 0; i < m_model->columnCount(); ++i)
213 visibleList.append(static_cast<int>(!isColumnHidden(i)));
220 QByteArray saveState = horizontalHeader()->saveState();
221 KConfig parleyConfig(
"parleyrc");
222 KConfigGroup documentGroup( &parleyConfig,
"Document " + m_doc->url().url() );
223 documentGroup.writeEntry(
"VocabularyColumns", horizontalHeader()->saveState() );
230 selectionModel()->clear();
231 selectionModel()->select(newIndex, QItemSelectionModel::ClearAndSelect);
232 selectionModel()->setCurrentIndex(newIndex, QItemSelectionModel::ClearAndSelect);
238 const QModelIndex &index = selectionModel()->currentIndex();
239 m_model->setData(index, QString(m_model->data(index).toString() + c));
245 foreach (
const QModelIndex &index, selectionModel()->selectedIndexes()) {
246 rows.insert(index.row());
250 if (askConfirmation) {
251 del = KMessageBox::Continue == KMessageBox::warningContinueCancel(
this, i18np(
"Do you really want to delete the selected entry?",
"Do you really want to delete the selected %1 entries?", rows.count()), i18n(
"Delete"), KStandardGuiItem::del());
256 while (!selectionModel()->selectedIndexes().isEmpty()) {
257 m_model->removeRows(selectionModel()->selectedIndexes()[0].row(), 1, QModelIndex());
264 QModelIndexList sortedIndexes = selectionModel()->selectedIndexes();
265 qSort(sortedIndexes);
266 QMimeData *mimeData = m_model->mimeData(sortedIndexes);
268 QClipboard *clipboard = KApplication::clipboard();
269 clipboard->setMimeData(mimeData);
274 QClipboard *clipboard = KApplication::clipboard();
275 const QMimeData *mimeData = clipboard->mimeData();
278 kDebug() <<
"Clipboard contains vocabulary mime data.";
280 KEduVocExpression *pasteExpression =
new KEduVocExpression(mimeEntry.
expression);
284 KEduVocWordType *type = m_doc->wordTypeContainer();
285 foreach (
int translation, mimeEntry.
wordTypes.keys()) {
287 foreach (
const QString& typeName, mimeEntry.
wordTypes.value(translation).wordType) {
288 kDebug() << mimeEntry.
wordTypes.value(translation).wordType;
289 KEduVocContainer *childType = type->childContainer(typeName);
292 childType =
new KEduVocWordType(typeName);
293 type->appendChildContainer(childType);
295 type =
static_cast<KEduVocWordType*
>(childType);
297 pasteExpression->translation(translation)->setWordType(type);
299 if (type->wordType() != mimeEntry.
wordTypes.value(translation).grammarType) {
300 if (type->wordType() == KEduVocWordFlag::NoInformation) {
301 type->setWordType(mimeEntry.
wordTypes.value(translation).grammarType);
306 }
else if (mimeData->hasText()) {
307 kDebug() <<
"Clipboard contains text data.";
309 QStringList lines = clipboard->text().split(
'\n');
310 foreach(QString line, lines) {
312 m_model->
appendEntry(
new KEduVocExpression(line.split(QRegExp(
"[\t;]"), QString::KeepEmptyParts)));
323 void VocabularyView::slotSelectionChanged(
const QItemSelection &,
const QItemSelection &)
325 bool hasSelection = selectionModel()->hasSelection();
326 m_deleteEntriesAction->setEnabled(hasSelection);
327 m_clearSelectionAction->setEnabled(hasSelection);
328 m_copyAction->setEnabled(hasSelection);
329 m_cutAction->setEnabled(hasSelection);
336 QTimer::singleShot(0,
this, SLOT(
reset()));
352 if ( dialog->exec() == KDialog::Accepted ) {
359 if (!m_model->rowCount()) {
360 KMessageBox::information(
this, i18n(
"Nothing to spell check."));
364 if (!m_spellChecker) {
365 m_spellChecker =
new Sonnet::BackgroundChecker(
this);
366 m_spellDialog =
new Sonnet::Dialog(m_spellChecker,
this);
367 connect(m_spellDialog, SIGNAL(done(
const QString&)),
this, SLOT(continueSpelling()));
368 connect(m_spellDialog, SIGNAL(misspelling(
const QString&,
int)),
this, SLOT(misspelling(
const QString&,
int)));
369 connect(m_spellDialog, SIGNAL(replace(
const QString&,
int,
const QString&)),
this, SLOT(spellingReplace(
const QString&,
int,
const QString&)));
374 if (m_spellColumn < 0) {
378 QModelIndex index = m_model->index(0, m_spellColumn);
379 QString locale = m_doc->identifier(language).locale();
382 m_spellChecker->changeLanguage(spellCode);
383 if (!m_spellChecker->speller().isValid()) {
384 kDebug() <<
"Invalid Language, popup here!";
385 KNotification::event(KNotification::Warning, i18nc(
"@title of a popup",
"No Spell Checker Available"), i18nc(
"@popupmessage",
"Either the language set up is incorrect or no spellchecker was installed for this locale: %1.", locale));
387 m_spellDialog->show();
391 void VocabularyView::continueSpelling()
393 kDebug() <<
"Check spelling: " << m_spellRow << m_spellColumn;
395 while (m_spellRow < m_model->rowCount()) {
396 QModelIndex index = m_model->index(m_spellRow, m_spellColumn);
397 kDebug() <<
" " << m_model->data(index).toString();
398 if (!m_model->data(index).toString().isEmpty()) {
399 m_spellDialog->setBuffer(m_model->data(index).toString());
407 void VocabularyView::selectIndex(
const QModelIndex &newIndex)
409 selectionModel()->select(newIndex, QItemSelectionModel::ClearAndSelect);
410 selectionModel()->setCurrentIndex(newIndex, QItemSelectionModel::ClearAndSelect);
414 bool VocabularyView::eventFilter(
QObject* obj, QEvent* event) {
416 QKeyEvent *keyEvent =
static_cast<QKeyEvent *
>(event);
417 if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
418 if (selectionModel()->currentIndex().row() == m_model->rowCount() - 1) {
424 return QObject::eventFilter(obj, event);
427 void VocabularyView::misspelling(
const QString & word,
int start)
431 QModelIndex index = m_model->index(m_spellRow, m_spellColumn);
435 void VocabularyView::spellingReplace(const QString & oldWord,
int start, const QString & newWord)
437 kDebug() << oldWord << start << newWord;
438 QModelIndex index = m_model->index(m_spellRow, m_spellColumn);
439 QString data = index.data().toString();
440 QString newData = data.replace(start, oldWord.length(), newWord);
441 kDebug() <<
"Changing " << data <<
" to " << newData;
442 m_model->setData(index, newData);
447 return selectionModel()->selectedIndexes();
450 #include "vocabularyview.moc"
void slotShowVocabularyColumnsDialog()
Show the vocabulary columns dialog to enable or disable the columns in the view.
Show options to enable/disable the columns for each language of the current document.
KEduVocExpression expression
QModelIndexList getSelectedIndexes() const
void slotCutEntry()
Cut an entry.
void setDocument(KEduVocDocument *doc)
VocabularyView(EditorWindow *parent)
void slotEditPaste()
paste the clipboard into the document
QList< int > visibleColumns() const
Get Visible columns in the main editor window.
QMap< int, WordTypeStrings > wordTypes
static int translation(int column)
Returns which translation this column matches.
void saveColumnVisibility() const
Save column visibility settings.
static int columnType(int column)
Returns the type of the column specified.
QList< VocabularyMimeData::MimeExpression > expressionList() const
void deleteSelectedEntries(bool askConfirmation=true)
Delete the currently selected entries.
static bool smartAppend()
Get If true, when using the entry dialog, new rows will be appended as needed.
void slotEditCopy()
put the marked text/object into the clipboard
QString spellChecker() const
Get Spell checker for this language.
void checkSpelling(int language)
Keeps the translated words.
void translationChanged(KEduVocExpression *, int)
void setTranslator(Translator *translator)
Set the translator to be used by the delegate.
void setDocument(KEduVocDocument *doc)
QModelIndex appendEntry(KEduVocExpression *expression=0)
void setModel(VocabularyFilter *model)
void setTranslator(Translator *translator)
Sets the member variable m_translator to a Translator object.
void appendChar(const QChar &c)
Append a char to the last edited entry (used to add the phonetic stuff).
void setVisibleColumns(const QList< int > &v)
Set Visible columns in the main editor window.