21 #include "tableactionmenu.h"
23 #include "inserttabledialog.h"
24 #include "tableformatdialog.h"
25 #include "tablecellformatdialog.h"
27 #include <KActionCollection>
30 #include <KLocalizedString>
36 namespace KPIMTextEdit {
38 class TableActionMenuPrivate
41 TableActionMenuPrivate( KActionCollection *ac, TextEdit *edit, TableActionMenu *qq )
42 : actionCollection( ac ), textEdit( edit ), q( qq )
46 void _k_slotInsertRowBelow();
47 void _k_slotInsertRowAbove();
48 void _k_slotInsertColumnBefore();
49 void _k_slotInsertColumnAfter();
51 void _k_slotInsertTable();
53 void _k_slotRemoveRowBelow();
54 void _k_slotRemoveRowAbove();
55 void _k_slotRemoveColumnBefore();
56 void _k_slotRemoveColumnAfter();
57 void _k_slotRemoveCellContents();
59 void _k_slotMergeCell();
60 void _k_slotMergeSelectedCells();
61 void _k_slotTableFormat();
62 void _k_slotTableCellFormat();
63 void _k_slotSplitCell();
64 void _k_updateActions(
bool forceUpdate =
false );
66 KAction *actionInsertTable;
68 KAction *actionInsertRowBelow;
69 KAction *actionInsertRowAbove;
71 KAction *actionInsertColumnBefore;
72 KAction *actionInsertColumnAfter;
74 KAction *actionRemoveRowBelow;
75 KAction *actionRemoveRowAbove;
77 KAction *actionRemoveColumnBefore;
78 KAction *actionRemoveColumnAfter;
80 KAction *actionMergeCell;
81 KAction *actionMergeSelectedCells;
82 KAction *actionSplitCell;
84 KAction *actionTableFormat;
85 KAction *actionTableCellFormat;
87 KAction *actionRemoveCellContents;
89 KActionCollection *actionCollection;
94 void TableActionMenuPrivate::_k_slotRemoveCellContents()
96 if ( textEdit->textMode() == KRichTextEdit::Rich ) {
97 QTextTable *table = textEdit->textCursor().currentTable();
98 const QTextTableCell cell = table->cellAt( textEdit->textCursor() );
99 if ( cell.isValid() ) {
100 const QTextCursor firstCursor = cell.firstCursorPosition();
101 const QTextCursor endCursor = cell.lastCursorPosition();
102 QTextCursor cursor = textEdit->textCursor();
103 cursor.beginEditBlock();
104 cursor.setPosition( firstCursor.position() );
105 cursor.movePosition( QTextCursor::NextCharacter, QTextCursor::KeepAnchor,
106 endCursor.position() - firstCursor.position() );
107 cursor.removeSelectedText();
108 cursor.endEditBlock();
113 void TableActionMenuPrivate::_k_slotRemoveRowBelow()
115 if ( textEdit->textMode() == KRichTextEdit::Rich ) {
116 QTextTable *table = textEdit->textCursor().currentTable();
118 const QTextTableCell cell = table->cellAt( textEdit->textCursor() );
119 if ( cell.row()<table->rows() - 1 ) {
120 table->removeRows( cell.row(), 1 );
126 void TableActionMenuPrivate::_k_slotRemoveRowAbove()
128 if ( textEdit->textMode() == KRichTextEdit::Rich ) {
129 QTextTable *table = textEdit->textCursor().currentTable();
131 const QTextTableCell cell = table->cellAt( textEdit->textCursor() );
132 if ( cell.row() >= 1 ) {
133 table->removeRows( cell.row() - 1, 1 );
139 void TableActionMenuPrivate::_k_slotRemoveColumnBefore()
141 if ( textEdit->textMode() == KRichTextEdit::Rich ) {
142 QTextTable *table = textEdit->textCursor().currentTable();
144 const QTextTableCell cell = table->cellAt( textEdit->textCursor() );
145 if ( cell.column() > 0 ) {
146 table->removeColumns( cell.column() - 1, 1 );
152 void TableActionMenuPrivate::_k_slotRemoveColumnAfter()
154 if ( textEdit->textMode() == KRichTextEdit::Rich ) {
155 QTextTable *table = textEdit->textCursor().currentTable();
157 const QTextTableCell cell = table->cellAt( textEdit->textCursor() );
158 if ( cell.column()<table->columns() - 1 ) {
159 table->removeColumns( cell.column(), 1 );
165 void TableActionMenuPrivate::_k_slotInsertRowBelow()
167 if ( textEdit->textMode() == KRichTextEdit::Rich ) {
168 QTextTable *table = textEdit->textCursor().currentTable();
170 const QTextTableCell cell = table->cellAt( textEdit->textCursor() );
171 if ( cell.row()<table->rows() ) {
172 table->insertRows( cell.row() + 1, 1 );
174 table->appendRows( 1 );
180 void TableActionMenuPrivate::_k_slotInsertRowAbove()
182 if ( textEdit->textMode() == KRichTextEdit::Rich ) {
183 QTextTable *table = textEdit->textCursor().currentTable();
185 const QTextTableCell cell = table->cellAt( textEdit->textCursor() );
186 table->insertRows( cell.row(), 1 );
191 void TableActionMenuPrivate::_k_slotInsertColumnBefore()
193 if ( textEdit->textMode() == KRichTextEdit::Rich ) {
194 QTextTable *table = textEdit->textCursor().currentTable();
196 const QTextTableCell cell = table->cellAt( textEdit->textCursor() );
197 table->insertColumns( cell.column(), 1 );
202 void TableActionMenuPrivate::_k_slotInsertColumnAfter()
204 if ( textEdit->textMode() == KRichTextEdit::Rich ) {
205 QTextTable *table = textEdit->textCursor().currentTable();
207 const QTextTableCell cell = table->cellAt( textEdit->textCursor() );
208 if ( cell.column()<table->columns() ) {
209 table->insertColumns( cell.column() + 1, 1 );
211 table->appendColumns( 1 );
217 void TableActionMenuPrivate::_k_slotInsertTable()
219 if ( textEdit->textMode() == KRichTextEdit::Rich ) {
220 QPointer<InsertTableDialog> dialog =
new InsertTableDialog( textEdit );
221 if ( dialog->exec() ) {
222 QTextCursor cursor = textEdit->textCursor();
223 QTextTableFormat tableFormat;
224 tableFormat.setBorder( dialog->border() );
225 const int numberOfColumns( dialog->columns() );
226 QVector<QTextLength> contrains;
227 const QTextLength::Type type = dialog->typeOfLength();
228 const int length = dialog->length();
230 const QTextLength textlength( type, length / numberOfColumns );
231 for (
int i = 0; i < numberOfColumns; ++i ) {
232 contrains.append( textlength );
234 tableFormat.setColumnWidthConstraints( contrains );
235 tableFormat.setAlignment(Qt::AlignLeft);
236 QTextTable *table = cursor.insertTable( dialog->rows(), numberOfColumns );
237 table->setFormat( tableFormat );
243 void TableActionMenuPrivate::_k_slotMergeCell()
245 if ( textEdit->textMode() == KRichTextEdit::Rich ) {
246 QTextTable *table = textEdit->textCursor().currentTable();
248 const QTextTableCell cell = table->cellAt( textEdit->textCursor() );
249 table->mergeCells( cell.row(), cell.column(), 1, cell.columnSpan() + 1 );
254 void TableActionMenuPrivate::_k_slotMergeSelectedCells()
256 if ( textEdit->textMode() == KRichTextEdit::Rich ) {
257 QTextTable *table = textEdit->textCursor().currentTable();
259 table->mergeCells( textEdit->textCursor() );
264 void TableActionMenuPrivate::_k_slotTableFormat()
266 if ( textEdit->textMode() == KRichTextEdit::Rich ) {
267 QTextTable *table = textEdit->textCursor().currentTable();
269 QPointer<TableFormatDialog> dialog =
new TableFormatDialog( textEdit );
270 const int numberOfColumn( table->columns() );
271 const int numberOfRow( table->rows() );
272 dialog->setColumns( numberOfColumn );
273 dialog->setRows( numberOfRow );
274 QTextTableFormat tableFormat = table->format();
275 dialog->setBorder( tableFormat.border() );
276 dialog->setSpacing( tableFormat.cellSpacing() );
277 dialog->setPadding( tableFormat.cellPadding() );
278 dialog->setAlignment( tableFormat.alignment() );
279 if ( tableFormat.hasProperty( QTextFormat::BackgroundBrush ) ) {
280 dialog->setTableBackgroundColor( tableFormat.background().color() );
282 QVector<QTextLength> contrains = tableFormat.columnWidthConstraints();
283 if ( !contrains.isEmpty() ) {
284 dialog->setTypeOfLength( contrains.at( 0 ).type() );
285 dialog->setLength( contrains.at( 0 ).rawValue() * numberOfColumn );
288 if ( dialog->exec() ) {
289 const int newNumberOfColumns( dialog->columns() );
290 if ( ( newNumberOfColumns != numberOfColumn ) ||
291 ( dialog->rows() != numberOfRow ) ) {
292 table->resize( dialog->rows(), newNumberOfColumns );
294 tableFormat.setBorder( dialog->border() );
295 tableFormat.setCellPadding( dialog->padding() );
296 tableFormat.setCellSpacing( dialog->spacing() );
297 tableFormat.setAlignment( dialog->alignment() );
299 QVector<QTextLength> contrains;
300 const QTextLength::Type type = dialog->typeOfLength();
301 const int length = dialog->length();
303 const QTextLength textlength( type, length / newNumberOfColumns );
304 for (
int i = 0; i < newNumberOfColumns; ++i ) {
305 contrains.append( textlength );
307 tableFormat.setColumnWidthConstraints( contrains );
308 const QColor tableBackgroundColor = dialog->tableBackgroundColor();
309 if ( dialog->useBackgroundColor() ) {
310 if ( tableBackgroundColor.isValid() ) {
311 tableFormat.setBackground( tableBackgroundColor );
314 tableFormat.clearBackground();
316 table->setFormat( tableFormat );
323 void TableActionMenuPrivate::_k_slotTableCellFormat()
325 if ( textEdit->textMode() == KRichTextEdit::Rich ) {
326 QTextTable *table = textEdit->textCursor().currentTable();
328 QTextTableCell cell = table->cellAt( textEdit->textCursor() );
329 QPointer<TableCellFormatDialog> dialog =
new TableCellFormatDialog( textEdit );
330 QTextTableCellFormat format = cell.format().toTableCellFormat();
331 if ( format.hasProperty( QTextFormat::BackgroundBrush ) ) {
332 dialog->setTableCellBackgroundColor( format.background().color() );
334 dialog->setVerticalAlignment( format.verticalAlignment() );
335 if ( dialog->exec() ) {
336 if ( dialog->useBackgroundColor() ) {
337 const QColor tableCellColor = dialog->tableCellBackgroundColor();
338 if ( tableCellColor.isValid() ) {
339 format.setBackground( tableCellColor );
342 format.clearBackground();
344 format.setVerticalAlignment( dialog->verticalAlignment() );
345 cell.setFormat( format );
352 void TableActionMenuPrivate::_k_slotSplitCell()
354 if ( textEdit->textMode() == KRichTextEdit::Rich ) {
355 QTextTable *table = textEdit->textCursor().currentTable();
357 const QTextTableCell cell = table->cellAt( textEdit->textCursor() );
358 if ( cell.columnSpan() > 1 || cell.rowSpan() > 1 ) {
359 table->splitCell( cell.row(), cell.column(),
360 qMax( 1, cell.rowSpan() - 1 ),
361 qMax( 1, cell.columnSpan() - 1 ) );
368 void TableActionMenuPrivate::_k_updateActions(
bool forceUpdate )
370 if ( ( textEdit->textMode() == KRichTextEdit::Rich ) || forceUpdate ) {
371 QTextTable *table = textEdit->textCursor().currentTable();
372 const bool isTable = ( table != 0 );
373 actionInsertRowBelow->setEnabled( isTable );
374 actionInsertRowAbove->setEnabled( isTable );
376 actionInsertColumnBefore->setEnabled( isTable );
377 actionInsertColumnAfter->setEnabled( isTable );
379 actionRemoveRowBelow->setEnabled( isTable );
380 actionRemoveRowAbove->setEnabled( isTable );
382 actionRemoveColumnBefore->setEnabled( isTable );
383 actionRemoveColumnAfter->setEnabled( isTable );
386 const QTextTableCell cell = table->cellAt( textEdit->textCursor() );
390 int firstColumn = -1;
392 textEdit->textCursor().selectedTableCells ( &firstRow, &numRows, &firstColumn, &numColumns );
393 const bool hasSelectedTableCell =
394 ( firstRow != -1 ) && ( numRows != -1 ) &&
395 ( firstColumn != -1 ) && ( numColumns != -1 );
396 if ( cell.column()>table->columns() - 2 ) {
397 actionMergeCell->setEnabled(
false );
399 actionMergeCell->setEnabled(
true );
401 if ( cell.columnSpan() > 1 || cell.rowSpan() > 1 ) {
402 actionSplitCell->setEnabled(
true );
404 actionSplitCell->setEnabled(
false );
406 actionTableCellFormat->setEnabled(
true );
407 actionMergeSelectedCells->setEnabled( hasSelectedTableCell );
409 actionSplitCell->setEnabled(
false );
410 actionMergeCell->setEnabled(
false );
411 actionMergeSelectedCells->setEnabled(
false );
413 actionTableFormat->setEnabled( isTable );
414 actionTableCellFormat->setEnabled( isTable );
415 actionRemoveCellContents->setEnabled( isTable );
419 TableActionMenu::TableActionMenu( KActionCollection *ac, TextEdit *textEdit )
420 : KActionMenu( textEdit ), d( new TableActionMenuPrivate( ac, textEdit, this ) )
422 KActionMenu *insertMenu =
new KActionMenu( i18n(
"Insert" ),
this );
423 addAction( insertMenu );
425 d->actionInsertTable =
new KAction( KIcon( QLatin1String(
"insert-table" ) ), i18n(
"Table..." ),
this );
426 insertMenu->addAction( d->actionInsertTable );
427 ac->addAction( QLatin1String(
"insert_new_table" ), d->actionInsertTable );
428 connect( d->actionInsertTable, SIGNAL(triggered(
bool)),
429 SLOT(_k_slotInsertTable()) );
431 insertMenu->addSeparator();
432 d->actionInsertRowBelow =
433 new KAction( KIcon( QLatin1String(
"edit-table-insert-row-below" ) ),
434 i18n(
"Row Below" ),
this );
435 insertMenu->addAction( d->actionInsertRowBelow );
436 ac->addAction( QLatin1String(
"insert_row_below" ), d->actionInsertRowBelow );
437 connect( d->actionInsertRowBelow, SIGNAL(triggered(
bool)),
438 SLOT(_k_slotInsertRowBelow()) );
440 d->actionInsertRowAbove =
441 new KAction( KIcon( QLatin1String(
"edit-table-insert-row-above" ) ),
442 i18n(
"Row Above" ),
this );
443 insertMenu->addAction( d->actionInsertRowAbove );
444 ac->addAction( QLatin1String(
"insert_row_above" ), d->actionInsertRowAbove );
445 connect( d->actionInsertRowAbove, SIGNAL(triggered(
bool)),
446 SLOT(_k_slotInsertRowAbove()) );
448 insertMenu->addSeparator();
449 d->actionInsertColumnBefore =
450 new KAction( KIcon( QLatin1String(
"edit-table-insert-column-left" ) ),
451 i18n(
"Column Before" ),
this );
452 insertMenu->addAction( d->actionInsertColumnBefore );
453 ac->addAction( QLatin1String(
"insert_column_before" ), d->actionInsertColumnBefore );
455 connect( d->actionInsertColumnBefore, SIGNAL(triggered(
bool)),
456 SLOT(_k_slotInsertColumnBefore()) );
458 d->actionInsertColumnAfter =
459 new KAction( KIcon( QLatin1String(
"edit-table-insert-column-right" ) ),
460 i18n(
"Column After" ),
this );
461 insertMenu->addAction( d->actionInsertColumnAfter );
462 ac->addAction( QLatin1String(
"insert_column_after" ), d->actionInsertColumnAfter );
463 connect( d->actionInsertColumnAfter, SIGNAL(triggered(
bool)),
464 SLOT(_k_slotInsertColumnAfter()) );
466 KActionMenu *removeMenu =
new KActionMenu( i18n(
"Delete" ),
this );
467 addAction( removeMenu );
469 d->actionRemoveRowBelow =
new KAction( i18n(
"Row Below" ),
this );
470 removeMenu->addAction( d->actionRemoveRowBelow );
471 ac->addAction( QLatin1String(
"remove_row_below" ), d->actionRemoveRowBelow );
472 connect( d->actionRemoveRowBelow, SIGNAL(triggered(
bool)),
473 SLOT(_k_slotRemoveRowBelow()) );
475 d->actionRemoveRowAbove =
new KAction( i18n(
"Row Above" ),
this );
476 removeMenu->addAction( d->actionRemoveRowAbove );
477 ac->addAction( QLatin1String(
"remove_row_above" ), d->actionRemoveRowAbove );
478 connect( d->actionRemoveRowAbove, SIGNAL(triggered(
bool)),
479 SLOT(_k_slotRemoveRowAbove()) );
481 removeMenu->addSeparator();
482 d->actionRemoveColumnBefore =
new KAction( i18n(
"Column Before" ),
this );
483 removeMenu->addAction( d->actionRemoveColumnBefore );
484 ac->addAction( QLatin1String(
"remove_column_before" ), d->actionRemoveColumnBefore );
486 connect( d->actionRemoveColumnBefore, SIGNAL(triggered(
bool)),
487 SLOT(_k_slotRemoveColumnBefore()) );
489 d->actionRemoveColumnAfter =
new KAction( i18n(
"Column After" ),
this );
490 removeMenu->addAction( d->actionRemoveColumnAfter );
491 ac->addAction( QLatin1String(
"remove_column_after" ), d->actionRemoveColumnAfter );
492 connect( d->actionRemoveColumnAfter, SIGNAL(triggered(
bool)),
493 SLOT(_k_slotRemoveColumnAfter()) );
495 removeMenu->addSeparator();
496 d->actionRemoveCellContents =
new KAction( i18n(
"Cell Contents" ),
this );
497 removeMenu->addAction( d->actionRemoveCellContents );
498 ac->addAction( QLatin1String(
"remove_cell_contents" ), d->actionRemoveCellContents );
499 connect( d->actionRemoveCellContents, SIGNAL(triggered(
bool)),
500 SLOT(_k_slotRemoveCellContents()) );
505 new KAction( KIcon( QLatin1String(
"edit-table-cell-merge" ) ),
506 i18n(
"Join With Cell to the Right" ),
this );
507 ac->addAction( QLatin1String(
"join_cell_to_the_right" ), d->actionMergeCell );
508 connect( d->actionMergeCell, SIGNAL(triggered(
bool)),
509 SLOT(_k_slotMergeCell()) );
510 addAction( d->actionMergeCell );
512 d->actionMergeSelectedCells =
new KAction( i18n(
"Join Selected Cells" ),
this );
513 ac->addAction( QLatin1String(
"join_cell_selected_cells" ), d->actionMergeSelectedCells );
514 connect( d->actionMergeSelectedCells, SIGNAL(triggered(
bool)),
515 SLOT(_k_slotMergeSelectedCells()) );
516 addAction( d->actionMergeSelectedCells );
519 new KAction( KIcon( QLatin1String(
"edit-table-cell-split" ) ),
520 i18n(
"Split cells" ),
this );
521 ac->addAction( QLatin1String(
"split_cells" ), d->actionSplitCell );
522 connect( d->actionSplitCell, SIGNAL(triggered(
bool)),
523 SLOT(_k_slotSplitCell()) );
524 addAction( d->actionSplitCell );
528 d->actionTableFormat =
new KAction( i18n(
"Table Format..." ),
this );
529 ac->addAction( QLatin1String(
"table_format" ), d->actionTableFormat );
530 connect( d->actionTableFormat, SIGNAL(triggered(
bool)),
531 SLOT(_k_slotTableFormat()) );
532 addAction( d->actionTableFormat );
534 d->actionTableCellFormat =
new KAction( i18n(
"Table Cell Format..." ),
this );
535 ac->addAction( QLatin1String(
"table_cell_format" ), d->actionTableCellFormat );
536 connect( d->actionTableCellFormat, SIGNAL(triggered(
bool)),
537 SLOT(_k_slotTableCellFormat()) );
538 addAction( d->actionTableCellFormat );
540 connect( textEdit, SIGNAL(cursorPositionChanged()),
541 this, SLOT(_k_updateActions()) );
542 d->_k_updateActions(
true );
545 TableActionMenu::~TableActionMenu()
552 #include "moc_tableactionmenu.cpp"