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.
496 lines
15 KiB
496 lines
15 KiB
15 years ago
|
/*******************************************************************
|
||
|
KNotes -- Notes for the KDE project
|
||
|
|
||
|
Copyright (c) 1997-2005, The KNotes Developers
|
||
|
|
||
|
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.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program; if not, write to the Free Software
|
||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
*******************************************************************/
|
||
|
|
||
|
#include <qdragobject.h>
|
||
|
#include <qfont.h>
|
||
|
|
||
|
#include <kdebug.h>
|
||
|
#include <klocale.h>
|
||
|
#include <kaction.h>
|
||
|
#include <kurldrag.h>
|
||
|
#include <kstdaction.h>
|
||
|
#include <kcolordialog.h>
|
||
|
|
||
|
#include "knoteedit.h"
|
||
|
|
||
|
static const short SEP = 5;
|
||
|
static const short ICON_SIZE = 10;
|
||
|
|
||
|
|
||
|
KNoteEdit::KNoteEdit( KActionCollection *actions, QWidget *parent, const char *name )
|
||
|
: KTextEdit( parent, name )
|
||
|
{
|
||
|
setAcceptDrops( true );
|
||
|
setWordWrap( WidgetWidth );
|
||
|
setWrapPolicy( AtWhiteSpace );
|
||
|
setLinkUnderline( true );
|
||
|
|
||
|
// create the actions for the RMB menu
|
||
|
KAction* undo = KStdAction::undo( this, SLOT(undo()), actions );
|
||
|
KAction* redo = KStdAction::redo( this, SLOT(redo()), actions );
|
||
|
undo->setEnabled( isUndoAvailable() );
|
||
|
redo->setEnabled( isRedoAvailable() );
|
||
|
|
||
|
m_cut = KStdAction::cut( this, SLOT(cut()), actions );
|
||
|
m_copy = KStdAction::copy( this, SLOT(copy()), actions );
|
||
|
m_paste = KStdAction::paste( this, SLOT(paste()), actions );
|
||
|
|
||
|
m_cut->setEnabled( false );
|
||
|
m_copy->setEnabled( false );
|
||
|
m_paste->setEnabled( true );
|
||
|
|
||
|
connect( this, SIGNAL(undoAvailable(bool)), undo, SLOT(setEnabled(bool)) );
|
||
|
connect( this, SIGNAL(redoAvailable(bool)), redo, SLOT(setEnabled(bool)) );
|
||
|
|
||
|
connect( this, SIGNAL(copyAvailable(bool)), m_cut, SLOT(setEnabled(bool)) );
|
||
|
connect( this, SIGNAL(copyAvailable(bool)), m_copy, SLOT(setEnabled(bool)) );
|
||
|
|
||
|
new KAction( KStdGuiItem::clear(), 0, this, SLOT(clear()), actions, "edit_clear" );
|
||
|
KStdAction::selectAll( this, SLOT(selectAll()), actions );
|
||
|
|
||
|
// create the actions modifying the text format
|
||
|
m_textBold = new KToggleAction( i18n("Bold"), "text_bold", CTRL + Key_B, 0, 0,
|
||
|
actions, "format_bold" );
|
||
|
m_textItalic = new KToggleAction( i18n("Italic"), "text_italic", CTRL + Key_I, 0, 0,
|
||
|
actions, "format_italic" );
|
||
|
m_textUnderline = new KToggleAction( i18n("Underline"), "text_under", CTRL + Key_U, 0, 0,
|
||
|
actions, "format_underline" );
|
||
|
m_textStrikeOut = new KToggleAction( i18n("Strike Out"), "text_strike", CTRL + Key_S, 0, 0,
|
||
|
actions, "format_strikeout" );
|
||
|
|
||
|
connect( m_textBold, SIGNAL(toggled(bool)), SLOT(setBold(bool)) );
|
||
|
connect( m_textItalic, SIGNAL(toggled(bool)), SLOT(setItalic(bool)) );
|
||
|
connect( m_textUnderline, SIGNAL(toggled(bool)), SLOT(setUnderline(bool)) );
|
||
|
connect( m_textStrikeOut, SIGNAL(toggled(bool)), SLOT(textStrikeOut(bool)) );
|
||
|
|
||
|
m_textAlignLeft = new KToggleAction( i18n("Align Left"), "text_left", ALT + Key_L,
|
||
|
this, SLOT(textAlignLeft()),
|
||
|
actions, "format_alignleft" );
|
||
|
m_textAlignLeft->setChecked( true ); // just a dummy, will be updated later
|
||
|
m_textAlignCenter = new KToggleAction( i18n("Align Center"), "text_center", ALT + Key_C,
|
||
|
this, SLOT(textAlignCenter()),
|
||
|
actions, "format_aligncenter" );
|
||
|
m_textAlignRight = new KToggleAction( i18n("Align Right"), "text_right", ALT + Key_R,
|
||
|
this, SLOT(textAlignRight()),
|
||
|
actions, "format_alignright" );
|
||
|
m_textAlignBlock = new KToggleAction( i18n("Align Block"), "text_block", ALT + Key_B,
|
||
|
this, SLOT(textAlignBlock()),
|
||
|
actions, "format_alignblock" );
|
||
|
|
||
|
m_textAlignLeft->setExclusiveGroup( "align" );
|
||
|
m_textAlignCenter->setExclusiveGroup( "align" );
|
||
|
m_textAlignRight->setExclusiveGroup( "align" );
|
||
|
m_textAlignBlock->setExclusiveGroup( "align" );
|
||
|
|
||
|
m_textList = new KToggleAction( i18n("List"), "enum_list", 0,
|
||
|
this, SLOT(textList()),
|
||
|
actions, "format_list" );
|
||
|
|
||
|
m_textList->setExclusiveGroup( "style" );
|
||
|
|
||
|
m_textSuper = new KToggleAction( i18n("Superscript"), "text_super", 0,
|
||
|
this, SLOT(textSuperScript()),
|
||
|
actions, "format_super" );
|
||
|
m_textSub = new KToggleAction( i18n("Subscript"), "text_sub", 0,
|
||
|
this, SLOT(textSubScript()),
|
||
|
actions, "format_sub" );
|
||
|
|
||
|
m_textSuper->setExclusiveGroup( "valign" );
|
||
|
m_textSub->setExclusiveGroup( "valign" );
|
||
|
|
||
|
// There is no easy possibility to implement text indenting with QTextEdit
|
||
|
//
|
||
|
// m_textIncreaseIndent = new KAction( i18n("Increase Indent"), "format_increaseindent", 0,
|
||
|
// this, SLOT(textIncreaseIndent()),
|
||
|
// actions, "format_increaseindent" );
|
||
|
//
|
||
|
// m_textDecreaseIndent = new KAction( i18n("Decrease Indent"), "format_decreaseindent", 0,
|
||
|
// this, SLOT(textDecreaseIndent()),
|
||
|
// actions, "format_decreaseindent" );
|
||
|
|
||
|
QPixmap pix( ICON_SIZE, ICON_SIZE );
|
||
|
pix.fill( black ); // just a dummy, gets updated before widget is shown
|
||
|
m_textColor = new KAction( i18n("Text Color..."), pix, 0, this,
|
||
|
SLOT(textColor()), actions, "format_color" );
|
||
|
|
||
|
m_textFont = new KFontAction( i18n("Text Font"), "text", KKey(),
|
||
|
actions, "format_font" );
|
||
|
connect( m_textFont, SIGNAL(activated( const QString & )),
|
||
|
this, SLOT(setFamily( const QString & )) );
|
||
|
|
||
|
m_textSize = new KFontSizeAction( i18n("Text Size"), KKey(),
|
||
|
actions, "format_size" );
|
||
|
connect( m_textSize, SIGNAL(fontSizeChanged( int )),
|
||
|
this, SLOT(setPointSize( int )) );
|
||
|
|
||
|
// QTextEdit connections
|
||
|
connect( this, SIGNAL(returnPressed()), SLOT(slotReturnPressed()) );
|
||
|
connect( this, SIGNAL(currentFontChanged( const QFont & )),
|
||
|
this, SLOT(fontChanged( const QFont & )) );
|
||
|
connect( this, SIGNAL(currentColorChanged( const QColor & )),
|
||
|
this, SLOT(colorChanged( const QColor & )) );
|
||
|
connect( this, SIGNAL(currentAlignmentChanged( int )),
|
||
|
this, SLOT(alignmentChanged( int )) );
|
||
|
connect( this, SIGNAL(currentVerticalAlignmentChanged( VerticalAlignment )),
|
||
|
this, SLOT(verticalAlignmentChanged( VerticalAlignment )) );
|
||
|
}
|
||
|
|
||
|
KNoteEdit::~KNoteEdit()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::setText( const QString& text )
|
||
|
{
|
||
|
// to update the font and font size combo box - QTextEdit stopped
|
||
|
// emitting the currentFontChanged signal with the new optimizations
|
||
|
KTextEdit::setText( text );
|
||
|
fontChanged( currentFont() );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::setTextFont( const QFont& font )
|
||
|
{
|
||
|
if ( textFormat() == PlainText )
|
||
|
setFont( font );
|
||
|
else
|
||
|
setCurrentFont( font );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::setTextColor( const QColor& color )
|
||
|
{
|
||
|
setColor( color );
|
||
|
colorChanged( color );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::setTabStop( int tabs )
|
||
|
{
|
||
|
QFontMetrics fm( font() );
|
||
|
setTabStopWidth( fm.width( 'x' ) * tabs );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::setAutoIndentMode( bool newmode )
|
||
|
{
|
||
|
m_autoIndentMode = newmode;
|
||
|
}
|
||
|
|
||
|
|
||
|
/** public slots **/
|
||
|
|
||
|
void KNoteEdit::setTextFormat( TextFormat f )
|
||
|
{
|
||
|
if ( f == textFormat() )
|
||
|
return;
|
||
|
|
||
|
if ( f == RichText )
|
||
|
{
|
||
|
QString t = text();
|
||
|
KTextEdit::setTextFormat( f );
|
||
|
|
||
|
// if the note contains html/xml source try to display it, otherwise
|
||
|
// get the modified text again and set it to preserve newlines
|
||
|
if ( QStyleSheet::mightBeRichText( t ) )
|
||
|
setText( t );
|
||
|
else
|
||
|
setText( text() );
|
||
|
|
||
|
enableRichTextActions();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
KTextEdit::setTextFormat( f );
|
||
|
QString t = text();
|
||
|
setText( t );
|
||
|
|
||
|
disableRichTextActions();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::textStrikeOut( bool s )
|
||
|
{
|
||
|
// QTextEdit does not support stroke out text (no saving,
|
||
|
// no changing of more than one selected character)
|
||
|
QFont font;
|
||
|
|
||
|
if ( !hasSelectedText() )
|
||
|
{
|
||
|
font = currentFont();
|
||
|
font.setStrikeOut( s );
|
||
|
setCurrentFont( font );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int pFrom, pTo, iFrom, iTo, iF, iT;
|
||
|
int cp, ci;
|
||
|
|
||
|
getSelection( &pFrom, &iFrom, &pTo, &iTo );
|
||
|
getCursorPosition( &cp, &ci );
|
||
|
|
||
|
for ( int p = pFrom; p <= pTo; p++ )
|
||
|
{
|
||
|
iF = 0;
|
||
|
iT = paragraphLength( p );
|
||
|
|
||
|
if ( p == pFrom )
|
||
|
iF = iFrom;
|
||
|
|
||
|
if ( p == pTo )
|
||
|
iT = iTo;
|
||
|
|
||
|
for ( int i = iF; i < iT; i++ )
|
||
|
{
|
||
|
setCursorPosition( p, i + 1 );
|
||
|
setSelection( p, i, p, i + 1 );
|
||
|
font = currentFont();
|
||
|
font.setStrikeOut( s );
|
||
|
setCurrentFont( font );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
setSelection( pFrom, iFrom, pTo, iTo );
|
||
|
setCursorPosition( cp, ci );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::textColor()
|
||
|
{
|
||
|
QColor c = color();
|
||
|
int ret = KColorDialog::getColor( c, this );
|
||
|
if ( ret == QDialog::Accepted )
|
||
|
setTextColor( c );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::textAlignLeft()
|
||
|
{
|
||
|
setAlignment( AlignLeft );
|
||
|
m_textAlignLeft->setChecked( true );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::textAlignCenter()
|
||
|
{
|
||
|
setAlignment( AlignCenter );
|
||
|
m_textAlignCenter->setChecked( true );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::textAlignRight()
|
||
|
{
|
||
|
setAlignment( AlignRight );
|
||
|
m_textAlignRight->setChecked( true );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::textAlignBlock()
|
||
|
{
|
||
|
setAlignment( AlignJustify );
|
||
|
m_textAlignBlock->setChecked( true );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::textList()
|
||
|
{
|
||
|
if ( m_textList->isChecked() )
|
||
|
setParagType( QStyleSheetItem::DisplayListItem, QStyleSheetItem::ListDisc );
|
||
|
else
|
||
|
setParagType( QStyleSheetItem::DisplayBlock, QStyleSheetItem::ListDisc );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::textSuperScript()
|
||
|
{
|
||
|
if ( m_textSuper->isChecked() )
|
||
|
setVerticalAlignment( AlignSuperScript );
|
||
|
else
|
||
|
setVerticalAlignment( AlignNormal );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::textSubScript()
|
||
|
{
|
||
|
if ( m_textSub->isChecked() )
|
||
|
setVerticalAlignment( AlignSubScript );
|
||
|
else
|
||
|
setVerticalAlignment( AlignNormal );
|
||
|
}
|
||
|
|
||
|
//void KNoteEdit::textIncreaseIndent()
|
||
|
//{
|
||
|
//}
|
||
|
|
||
|
//void KNoteEdit::textDecreaseIndent()
|
||
|
//{
|
||
|
//}
|
||
|
|
||
|
|
||
|
/** protected methods **/
|
||
|
|
||
|
void KNoteEdit::contentsDragEnterEvent( QDragEnterEvent *e )
|
||
|
{
|
||
|
if ( KURLDrag::canDecode( e ) )
|
||
|
e->accept();
|
||
|
else
|
||
|
KTextEdit::contentsDragEnterEvent( e );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::contentsDropEvent( QDropEvent *e )
|
||
|
{
|
||
|
KURL::List list;
|
||
|
|
||
|
if ( KURLDrag::decode( e, list ) )
|
||
|
for ( KURL::List::Iterator it = list.begin(); it != list.end(); ++it )
|
||
|
{
|
||
|
if ( it != list.begin() )
|
||
|
insert( ", " );
|
||
|
|
||
|
insert( (*it).prettyURL() );
|
||
|
}
|
||
|
else
|
||
|
KTextEdit::contentsDropEvent( e );
|
||
|
}
|
||
|
|
||
|
/** private slots **/
|
||
|
|
||
|
void KNoteEdit::slotReturnPressed()
|
||
|
{
|
||
|
if ( m_autoIndentMode )
|
||
|
autoIndent();
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::fontChanged( const QFont &f )
|
||
|
{
|
||
|
m_textFont->setFont( f.family() );
|
||
|
m_textSize->setFontSize( f.pointSize() );
|
||
|
|
||
|
m_textBold->setChecked( f.bold() );
|
||
|
m_textItalic->setChecked( f.italic() );
|
||
|
m_textUnderline->setChecked( f.underline() );
|
||
|
m_textStrikeOut->setChecked( f.strikeOut() );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::colorChanged( const QColor &c )
|
||
|
{
|
||
|
QPixmap pix( ICON_SIZE, ICON_SIZE );
|
||
|
pix.fill( c );
|
||
|
m_textColor->setIconSet( pix );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::alignmentChanged( int a )
|
||
|
{
|
||
|
// TODO: AlignAuto
|
||
|
if ( ( a == AlignAuto ) || ( a & AlignLeft ) )
|
||
|
m_textAlignLeft->setChecked( true );
|
||
|
else if ( ( a & AlignHCenter ) )
|
||
|
m_textAlignCenter->setChecked( true );
|
||
|
else if ( ( a & AlignRight ) )
|
||
|
m_textAlignRight->setChecked( true );
|
||
|
else if ( ( a & AlignJustify ) )
|
||
|
m_textAlignBlock->setChecked( true );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::verticalAlignmentChanged( VerticalAlignment a )
|
||
|
{
|
||
|
if ( a == AlignNormal )
|
||
|
{
|
||
|
m_textSuper->setChecked( false );
|
||
|
m_textSub->setChecked( false );
|
||
|
}
|
||
|
else if ( a == AlignSuperScript )
|
||
|
m_textSuper->setChecked( true );
|
||
|
else if ( a == AlignSubScript )
|
||
|
m_textSub->setChecked( true );
|
||
|
}
|
||
|
|
||
|
|
||
|
/** private methods **/
|
||
|
|
||
|
void KNoteEdit::autoIndent()
|
||
|
{
|
||
|
int para, index;
|
||
|
QString string;
|
||
|
getCursorPosition( ¶, &index );
|
||
|
while ( para > 0 && string.stripWhiteSpace().isEmpty() )
|
||
|
string = text( --para );
|
||
|
|
||
|
if ( string.stripWhiteSpace().isEmpty() )
|
||
|
return;
|
||
|
|
||
|
// This routine returns the whitespace before the first non white space
|
||
|
// character in string.
|
||
|
// It is assumed that string contains at least one non whitespace character
|
||
|
// ie \n \r \t \v \f and space
|
||
|
QString indentString;
|
||
|
|
||
|
int len = string.length();
|
||
|
int i = 0;
|
||
|
while ( i < len && string.at(i).isSpace() )
|
||
|
indentString += string.at( i++ );
|
||
|
|
||
|
if ( !indentString.isEmpty() )
|
||
|
insert( indentString );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::emitLinkClicked( const QString &s )
|
||
|
{
|
||
|
kdDebug(5500) << k_funcinfo << s << endl;
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::enableRichTextActions()
|
||
|
{
|
||
|
m_textColor->setEnabled( true );
|
||
|
m_textFont->setEnabled( true );
|
||
|
m_textSize->setEnabled( true );
|
||
|
|
||
|
m_textBold->setEnabled( true );
|
||
|
m_textItalic->setEnabled( true );
|
||
|
m_textUnderline->setEnabled( true );
|
||
|
m_textStrikeOut->setEnabled( true );
|
||
|
|
||
|
m_textAlignLeft->setEnabled( true );
|
||
|
m_textAlignCenter->setEnabled( true );
|
||
|
m_textAlignRight->setEnabled( true );
|
||
|
m_textAlignBlock->setEnabled( true );
|
||
|
|
||
|
m_textList->setEnabled( true );
|
||
|
m_textSuper->setEnabled( true );
|
||
|
m_textSub->setEnabled( true );
|
||
|
|
||
|
// m_textIncreaseIndent->setEnabled( true );
|
||
|
// m_textDecreaseIndent->setEnabled( true );
|
||
|
}
|
||
|
|
||
|
void KNoteEdit::disableRichTextActions()
|
||
|
{
|
||
|
m_textColor->setEnabled( false );
|
||
|
m_textFont->setEnabled( false );
|
||
|
m_textSize->setEnabled( false );
|
||
|
|
||
|
m_textBold->setEnabled( false );
|
||
|
m_textItalic->setEnabled( false );
|
||
|
m_textUnderline->setEnabled( false );
|
||
|
m_textStrikeOut->setEnabled( false );
|
||
|
|
||
|
m_textAlignLeft->setEnabled( false );
|
||
|
m_textAlignCenter->setEnabled( false );
|
||
|
m_textAlignRight->setEnabled( false );
|
||
|
m_textAlignBlock->setEnabled( false );
|
||
|
|
||
|
m_textList->setEnabled( false );
|
||
|
m_textSuper->setEnabled( false );
|
||
|
m_textSub->setEnabled( false );
|
||
|
|
||
|
// m_textIncreaseIndent->setEnabled( false );
|
||
|
// m_textDecreaseIndent->setEnabled( false );
|
||
|
}
|
||
|
|
||
|
#include "knoteedit.moc"
|