texteditor.cpp
author insilmaril
Fri Jul 08 07:24:43 2005 +0000 (2005-07-08)
changeset 121 7aa2e46c00f1
parent 95 f688a9913724
child 123 09edde7ae30e
permissions -rw-r--r--
changes for 1.6.9
     1 #include "texteditor.h"
     2 
     3 #include <qcanvas.h>
     4 #include <qstatusbar.h>
     5 #include <qmessagebox.h>
     6 #include <qaction.h>
     7 #include <qapplication.h>
     8 #include <qpainter.h>
     9 #include <qprinter.h>
    10 #include <qfile.h>
    11 #include <qfiledialog.h>
    12 #include <qtoolbar.h>
    13 #include <qpopupmenu.h>
    14 #include <qmenubar.h>
    15 #include <qtextedit.h>
    16 #include <qaccel.h>
    17 #include <qtextstream.h>
    18 #include <qpaintdevicemetrics.h>
    19 #include <qsettings.h>
    20 #include <qfontdialog.h>
    21 #include <qmessagebox.h>
    22 #include <qcolordialog.h>
    23 #include <qregexp.h>
    24 #include <qlineedit.h>
    25 #include <qsimplerichtext.h>
    26 
    27 #include <iostream>
    28 #include <cstdlib>
    29 #include <typeinfo>
    30 
    31 #include "icons/fileopen.xpm"
    32 #include "icons/filesave.xpm"
    33 #include "icons/fileprint.xpm"
    34 #include "icons/editundo.xpm"	
    35 #include "icons/editredo.xpm"	
    36 #include "icons/editcopy.xpm"
    37 #include "icons/editcut.xpm"
    38 #include "icons/editpaste.xpm"
    39 #include "icons/edittrash.xpm"
    40 #include "icons/formatfixedfont.xpm"
    41 #include "icons/formattextbold.xpm"
    42 #include "icons/formattextitalic.xpm"
    43 #include "icons/formattextunder.xpm"
    44 #include "icons/formattextleft.xpm"
    45 #include "icons/formattextcenter.xpm"
    46 #include "icons/formattextright.xpm"
    47 #include "icons/formattextjustify.xpm"
    48 
    49 extern QCanvas* actCanvas;
    50 extern int statusbarTime;
    51 extern QSettings settings;
    52 
    53 extern QAction *actionViewToggleNoteEditor;
    54 
    55 using namespace std;
    56 
    57 
    58 ///////////////////////////////////////////////////////////////////////
    59 ///////////////////////////////////////////////////////////////////////
    60 
    61 TextEditor::TextEditor()
    62 {
    63     printer = new QPrinter( QPrinter::HighResolution );
    64 
    65 	// Editor
    66     e = new QTextEdit( this, "editor" );
    67     e->setFocus();
    68 	e->setTextFormat(RichText);		// default
    69 	e->setTabStopWidth (20);		// unit is pixel
    70 	e->setColor (black);
    71 	connect (e, SIGNAL( textChanged() ), this, SLOT( editorChanged() ) );
    72     setCentralWidget( e );
    73     statusBar()->message( "Ready", statusbarTime);
    74 	setCaption("VYM - Note Editor");
    75 
    76 	// Toolbars
    77 	setupFileActions();
    78 	setupEditActions();
    79 	setupFormatActions();
    80 	setupSettingsActions();
    81 	
    82 	// Various states
    83 	emptyPaper   = QBrush(gray);
    84 	filledPaper  = QBrush(white);
    85 	inactivePaper= QBrush(black);
    86 	setInactive();
    87 
    88 	// Load Settings
    89 	resize (settings.readNumEntry( "/vym/noteeditor/geometry/width", 450),
    90 	        settings.readNumEntry( "/vym/noteeditor/geometry/height",600));
    91 	move   (settings.readNumEntry( "/vym/noteeditor/geometry/posX", 150),
    92 	        settings.readNumEntry( "/vym/noteeditor/geometry/posY",  50));
    93 	
    94 	if (settings.readEntry( "/vym/noteeditor/showWithMain","yes") =="yes")
    95 		setShowWithMain(true);
    96 	else	
    97 		setShowWithMain(false);
    98 
    99 	varFont.fromString( settings.readEntry 
   100 		("/vym/noteeditor/fonts/varFont",
   101 		"Nimbus Sans l,14,-1,5,48,0,0,0,0,0") 
   102 	);
   103 	fixedFont.fromString (settings.readEntry (
   104 		"/vym/noteeditor/fonts/fixedFont",
   105 		"Courier,14,-1,5,48,0,0,0,1,0") 
   106 	);
   107 	QString s=settings.readEntry ("/vym/noteeditor/fonts/fonthintDefault","variable");
   108 	if (s == "fixed")
   109 	{	
   110 		actionSettingsFonthintDefault->setOn (true);
   111 		e->setCurrentFont (fixedFont);
   112 	} else	
   113 	{
   114 		actionSettingsFonthintDefault->setOn (false);
   115 		e->setCurrentFont (varFont);
   116 	}	
   117 	filenameHint="";
   118 }
   119 
   120 
   121 TextEditor::~TextEditor()
   122 {
   123     if (printer) delete printer;
   124 	// Save Settings
   125 	settings.writeEntry( "/vym/noteeditor/geometry/width", width() );
   126 	settings.writeEntry( "/vym/noteeditor/geometry/height", height() );
   127 	settings.writeEntry( "/vym/noteeditor/geometry/posX", pos().x() );
   128 	settings.writeEntry( "/vym/noteeditor/geometry/posY", pos().y() );
   129 	
   130 	if (showWithMain())
   131 		settings.writeEntry( "/vym/noteeditor/showWithMain","yes");
   132 	else	
   133 		settings.writeEntry( "/vym/noteeditor/showWithMain","no");
   134 
   135 	QString s;
   136 	if (actionSettingsFonthintDefault->isOn() )
   137 		s="fixed";
   138 	else	
   139 		s="variable";
   140 	settings.writeEntry( "/vym/noteeditor/fonts/fonthintDefault",s );
   141 	settings.writeEntry ("/vym/noteeditor/fonts/varFont",
   142 		varFont.toString() );
   143 	settings.writeEntry ("/vym/noteeditor/fonts/fixedFont",
   144 		fixedFont.toString() );
   145 }
   146 
   147 bool TextEditor::isEmpty()
   148 {
   149 	if (e->text().length())
   150 		return false;
   151 	else
   152 		return true;
   153 }
   154 
   155 void TextEditor::setShowWithMain(bool v)
   156 {
   157 	showwithmain=v;
   158 }
   159 
   160 bool TextEditor::showWithMain()
   161 {
   162 	return showwithmain;
   163 }
   164 
   165 void TextEditor::setFontHint (const QString &fh)
   166 {
   167 	if (fh=="fixed")
   168 		actionFormatUseFixedFont->setOn (true);
   169 	else
   170 		actionFormatUseFixedFont->setOn (false);
   171 }
   172 
   173 
   174 QString TextEditor::getFontHint()
   175 {
   176 	if (actionFormatUseFixedFont->isOn())
   177 		return "fixed";
   178 	else	
   179 		return "var";
   180 }
   181 
   182 QString TextEditor::getFontHintDefault()
   183 {
   184 	if (actionSettingsFonthintDefault->isOn())
   185 		return "fixed";
   186 	else	
   187 		return "var";
   188 }
   189 
   190 void TextEditor::setFilename(const QString &fn)
   191 {
   192 	if (state==filledEditor)
   193 		if (fn.isEmpty() )
   194 		{
   195 			filename="";
   196 			statusBar()->message( "No filename available for this note.", statusbarTime );
   197 		}	
   198 		else
   199 		{
   200 			filename=fn;
   201 			statusBar()->message( QString( "Current filename is %1" ).arg( filename ), statusbarTime );
   202 		}	
   203 }
   204 
   205 QString TextEditor::getFilename()
   206 {
   207 	return filename;
   208 }
   209 
   210 void TextEditor::setFilenameHint(const QString &fnh)
   211 {
   212 	filenameHint=fnh;
   213 }
   214 
   215 QString TextEditor::getFilenameHint()
   216 {
   217 	return filenameHint;
   218 }
   219 
   220 bool TextEditor::findText(const QString &t, const bool &cs)
   221 {
   222 	bool wo=false;	// word matches
   223 	if (e->find (t, cs, wo, true, 0, 0 ))
   224 		return true;
   225 	else	
   226 		return false;
   227 }
   228 
   229 void TextEditor::setupFileActions()
   230 {
   231     QToolBar *tb = new QToolBar( this );
   232     tb->setLabel( "File Actions" );
   233     QPopupMenu *menu = new QPopupMenu( this );
   234     menuBar()->insertItem( tr( "&File" ), menu );
   235 
   236     QAction *a;
   237     a = new QAction( tr( "Import" ), QPixmap( fileopen_xpm), tr( "&Import..." ), CTRL + Key_O, this, "fileImport" );
   238     connect( a, SIGNAL( activated() ), this, SLOT( textLoad() ) );
   239 	a->setEnabled(false);
   240     a->addTo( tb );
   241     a->addTo( menu );
   242 	actionFileLoad=a;
   243 
   244     menu->insertSeparator();
   245     a = new QAction( tr( "Export Note (HTML)" ), QPixmap( filesave_xpm ), tr( "&Export..." ), CTRL + Key_S, this, "fileSave" );
   246     connect( a, SIGNAL( activated() ), this, SLOT( textSave() ) );
   247     a->addTo( tb );
   248     a->addTo( menu );
   249 	actionFileSave=a;
   250 	
   251     a = new QAction( tr( "Export Note As (HTML) " ), QPixmap(), tr( "Export &As... (HTML)" ), 0, this, "exportHTML" );
   252     connect( a, SIGNAL( activated() ), this, SLOT( textSaveAs() ) );
   253     a->addTo( menu );
   254 	actionFileSaveAs=a;
   255 
   256     a = new QAction( tr( "Export Note As (ASCII) " ), QPixmap(), tr( "Export &As...(ASCII)" ), ALT + Key_X, this, "exportASCII" );
   257     connect( a, SIGNAL( activated() ), this, SLOT( textExportAsASCII() ) );
   258     a->addTo( menu );
   259 	actionFileSaveAs=a;
   260 
   261     menu->insertSeparator();
   262     a = new QAction( tr( "Print Note" ), QPixmap( fileprint_xpm ), tr( "&Print..." ), CTRL + Key_P, this, "filePrint" );
   263     connect( a, SIGNAL( activated() ), this, SLOT( textPrint() ) );
   264     a->addTo( tb );
   265     a->addTo( menu );
   266 	actionFilePrint=a;
   267 }
   268 
   269 void TextEditor::setupEditActions()
   270 {
   271     QToolBar *tb = new QToolBar( this );
   272     tb->setLabel( "Edit Actions" );
   273     QPopupMenu *menu = new QPopupMenu( this );
   274     menuBar()->insertItem( tr( "&Edit" ), menu );
   275 
   276     QAction *a;
   277     a = new QAction( tr( "Undo" ), QPixmap(editundo_xpm), tr( "&Undo" ), CTRL + Key_Z, this, "undoEvent" );
   278     connect( a, SIGNAL( activated() ), e, SLOT( undo() ) );
   279     a->addTo( menu );
   280     a->addTo( tb);
   281 	actionEditUndo=a;
   282 	
   283     a = new QAction( tr( "Redo" ), QPixmap( editredo_xpm ), tr( "&Redo" ), CTRL + Key_Y, this, "editRedo" ); 
   284     connect( a, SIGNAL( activated() ), e, SLOT( redo() ) );
   285     a->addTo( tb );
   286     a->addTo( menu );
   287 	actionEditRedo=a;
   288 
   289     menu->insertSeparator();
   290     a = new QAction( tr( "Select and copy all" ), QPixmap(), tr( "Select and copy &all" ), CTRL + Key_A, this, "editcopyall" ); 
   291     connect( a, SIGNAL( activated() ), this, SLOT( editCopyAll() ) );
   292     a->addTo( menu );
   293 
   294     menu->insertSeparator();
   295     a = new QAction( tr( "Copy" ), QPixmap( editcopy_xpm ), tr( "&Copy" ), CTRL + Key_C, this, "editCopy" );
   296     connect( a, SIGNAL( activated() ), e, SLOT( copy() ) );
   297     a->addTo( tb );
   298     a->addTo( menu );
   299 	actionEditCopy=a;
   300 	
   301     a = new QAction( tr( "Cut" ), QPixmap( editcut_xpm ), tr( "Cu&t" ), CTRL + Key_X, this, "editCut" );
   302     connect( a, SIGNAL( activated() ), e, SLOT( cut() ) );
   303     a->addTo( tb );
   304     a->addTo( menu );
   305 	actionEditCut=a;
   306 
   307     a = new QAction( tr( "Paste" ), QPixmap( editpaste_xpm ), tr( "&Paste" ), CTRL + Key_V, this, "editPaste" );
   308     connect( a, SIGNAL( activated() ), e, SLOT( paste() ) );
   309     a->addTo( tb );
   310     a->addTo( menu );
   311 	actionEditPaste=a;
   312 	
   313     a = new QAction( tr( "Delete all" ), QPixmap( edittrash_xpm ), tr( "&Delete All" ), 0, this, "editDeleteAll" );
   314     connect( a, SIGNAL( activated() ), e, SLOT( clear() ) );
   315     a->addTo( tb );
   316     a->addTo( menu );
   317 	actionEditDeleteAll=a;
   318 
   319 	a = new QAction( tr( "Convert paragraphs to linebreaks" ), QPixmap(), tr( "&Convert Paragraphs" ), ALT + Key_P, this, "editConvertPar" );
   320     connect( a, SIGNAL( activated() ), this, SLOT( textConvertPar() ) );
   321     a->addTo( menu );
   322 	actionEditConvertPar=a;
   323 
   324 	a = new QAction( tr( "Join all lines of a paragraph" ), QPixmap(), tr( "&Join lines" ), ALT + Key_J, this, "editJoinLines" );
   325     connect( a, SIGNAL( activated() ), this, SLOT( textJoinLines() ) );
   326     a->addTo( menu );
   327 	actionEditJoinLines=a;
   328 }
   329 
   330 void TextEditor::setupFormatActions()
   331 {
   332     QToolBar *tb = new QToolBar( this );
   333     tb->setLabel( "Format Actions" );
   334     QPopupMenu *menu = new QPopupMenu( this );
   335     menuBar()->insertItem( tr( "&Format" ), menu );
   336 
   337     QAction *a;
   338 
   339     a = new QAction( tr( "Toggle font hint for the whole text" ), QPixmap(formatfixedfont_xpm), tr( "&Font hint" ), ALT + Key_I, this, "fontHint" );
   340 	a->setToggleAction (true);
   341 	a->setOn (settings.readBoolEntry ("/vym/noteeditor/fonts/useFixedByDefault",false) );
   342     connect( a, SIGNAL( activated() ), this, SLOT( toggleFonthint() ) );
   343     a->addTo( menu );
   344     a->addTo( tb );
   345 	actionFormatUseFixedFont=a;
   346 
   347 	menu->insertSeparator();
   348 
   349     comboFont = new QComboBox( true, tb );
   350     QFontDatabase db;
   351     comboFont->insertStringList( db.families() );
   352     connect( comboFont, SIGNAL( activated( const QString & ) ),
   353 	     this, SLOT( textFamily( const QString & ) ) );
   354     comboFont->lineEdit()->setText( QApplication::font().family() );
   355 
   356     comboSize = new QComboBox( true, tb );
   357     QValueList<int> sizes = db.standardSizes();
   358     QValueList<int>::Iterator it = sizes.begin();
   359     for ( ; it != sizes.end(); ++it )
   360 	comboSize->insertItem( QString::number( *it ) );
   361     connect( comboSize, SIGNAL( activated( const QString & ) ),
   362 	     this, SLOT( textSize( const QString & ) ) );
   363     comboSize->lineEdit()->setText( QString::number( QApplication::font().pointSize() ) );
   364 
   365     menu->insertSeparator();
   366 
   367     QPixmap pix( 16, 16 );
   368     pix.fill( e->color());
   369     actionTextColor = new QAction( pix, tr( "&Color..." ), 0, this, "textColor" );
   370     connect( actionTextColor, SIGNAL( activated() ), this, SLOT( textColor() ) );
   371     actionTextColor->addTo( tb );
   372     actionTextColor->addTo( menu );
   373 
   374     actionTextBold = new QAction( QPixmap (formattextbold_xpm), tr( "&Bold" ), CTRL + Key_B, this, "textBold" );
   375     connect( actionTextBold, SIGNAL( activated() ), this, SLOT( textBold() ) );
   376     actionTextBold->addTo( tb );
   377     actionTextBold->addTo( menu );
   378     actionTextBold->setToggleAction( true );
   379     actionTextItalic = new QAction( QPixmap(formattextitalic_xpm ), tr( "&Italic" ), CTRL + Key_I, this, "textItalic" );
   380     connect( actionTextItalic, SIGNAL( activated() ), this, SLOT( textItalic() ) );
   381     actionTextItalic->addTo( tb );
   382     actionTextItalic->addTo( menu );
   383     actionTextItalic->setToggleAction( true );
   384     actionTextUnderline = new QAction( QPixmap (formattextunder_xpm ), tr( "&Underline" ), CTRL + Key_U, this, "textUnderline" );
   385     connect( actionTextUnderline, SIGNAL( activated() ), this, SLOT( textUnderline() ) );
   386     actionTextUnderline->addTo( tb );
   387     actionTextUnderline->addTo( menu );
   388     actionTextUnderline->setToggleAction( true );
   389     menu->insertSeparator();
   390 
   391     QActionGroup *grp = new QActionGroup( this );
   392     connect( grp, SIGNAL( selected( QAction* ) ), this, SLOT( textAlign( QAction* ) ) );
   393 
   394     actionAlignLeft = new QAction( QPixmap (formattextleft_xpm ), tr( "&Left" ), CTRL + Key_L, grp, "textLeft" );
   395     actionAlignLeft->setToggleAction( true );
   396     actionAlignCenter = new QAction( QPixmap (formattextcenter_xpm ), tr( "C&enter" ), CTRL + Key_E, grp, "textCenter" );
   397     actionAlignCenter->setToggleAction( true );
   398     actionAlignRight = new QAction( QPixmap (formattextright_xpm ), tr( "&Right" ), CTRL + Key_R, grp, "textRight" );
   399     actionAlignRight->setToggleAction( true );
   400     actionAlignJustify = new QAction( QPixmap ( formattextjustify_xpm ), tr( "&Justify" ), CTRL + Key_J, grp, "textjustify" );
   401     actionAlignJustify->setToggleAction( true );
   402 
   403     grp->addTo( tb );
   404     grp->addTo( menu );
   405 
   406     connect( e, SIGNAL( currentFontChanged( const QFont & ) ),
   407 	     this, SLOT( fontChanged( const QFont & ) ) );
   408     connect( e, SIGNAL( currentColorChanged( const QColor & ) ),
   409 	     this, SLOT( colorChanged( const QColor & ) ) );
   410     connect( e, SIGNAL( currentAlignmentChanged( int ) ),
   411 	     this, SLOT( alignmentChanged( int ) ) );
   412 
   413 }
   414 
   415 void TextEditor::setupSettingsActions()
   416 {
   417     QPopupMenu *menu = new QPopupMenu( this );
   418     menuBar()->insertItem( tr( "&Settings" ), menu );
   419 
   420     QAction *a;
   421     a = new QAction( tr( "Set fixed font" ), QPixmap(), tr( "Set &fixed font" ), 0, this, "setFixedFont" );
   422     connect( a, SIGNAL( activated() ), this, SLOT( setFixedFont() ) );
   423     a->addTo( menu );
   424 	actionSettingsFixedFont=a;
   425 
   426     a = new QAction( tr( "Set variable font" ), QPixmap(), tr( "Set &variable font" ), 0, this, "setvariableFont" );
   427     connect( a, SIGNAL( activated() ), this, SLOT( setVarFont() ) );
   428     a->addTo( menu );
   429 	actionSettingsVarFont=a;
   430 
   431     a = new QAction( tr( "Used fixed font by default" ), QPixmap(), tr( "&fixed font is default" ), 0, this, "fonthintDefault" );
   432 	a->setToggleAction (true);
   433 	// set state later in constructor...
   434     a->addTo( menu );
   435 	actionSettingsFonthintDefault=a;
   436 }
   437 
   438 void TextEditor::textLoad()
   439 {
   440 	if (state!=inactiveEditor)
   441 	{
   442 		if (e->length()) 
   443 		{
   444 			QMessageBox mb( "VYM - Note Editor",
   445 				"Loading will overwrite the existing note",
   446 				QMessageBox::Warning,
   447 				QMessageBox::Yes | QMessageBox::Default,
   448 				QMessageBox::Cancel,
   449 				0 );
   450 			mb.setButtonText( QMessageBox::Yes, "Load note" );
   451 			switch( mb.exec() ) {
   452 				case QMessageBox::Cancel:
   453 					return;
   454 					break;
   455 			}
   456 		} 
   457 		// Load note
   458 		QFileDialog *fd=new QFileDialog( this);
   459 		fd->addFilter ("ASCII texts (*.txt)");
   460 		fd->addFilter ("VYM notes (*.html)");
   461 		fd->show();
   462 		QString fn;
   463 		if ( fd->exec() == QDialog::Accepted )
   464 			fn = fd->selectedFile();
   465 
   466 		if ( !fn.isEmpty() )
   467 		{
   468 			QFile f( fn );
   469 			if ( !f.open( IO_ReadOnly ) )
   470 			return;
   471 
   472 			QTextStream ts( &f );
   473 			setText( ts.read() );
   474 			editorChanged();
   475 		}
   476 	}
   477 }
   478 
   479 void TextEditor::closeEvent( QCloseEvent* ce )
   480 {
   481     if ( !e->isModified() ) 
   482 	{
   483 		ce->accept();	// TextEditor can be reopened with show()
   484 		actionViewToggleNoteEditor->setOn (false);
   485 		showwithmain=false;
   486 		return;
   487     }
   488 }
   489 
   490 QString TextEditor::getText()
   491 {
   492 	return e->text();
   493 }
   494 
   495 void TextEditor::editorChanged()
   496 {
   497 	// received, when QTextEdit::text() has changed
   498 	EditorState	oldstate=state;
   499 
   500 	if (isEmpty())
   501 		state=emptyEditor;
   502 	else
   503 		state=filledEditor;
   504 
   505 	if (state != oldstate)
   506 	{
   507 		if (state==emptyEditor)
   508 			e->setPaper (emptyPaper);
   509 		else
   510 			e->setPaper (filledPaper);
   511 	}
   512 	// SLOT is LinkableMapObj, which will update systemFlag
   513 	emit (textHasChanged() );
   514 }
   515 
   516 
   517 void TextEditor::setText(QString t)
   518 {
   519 	if ( !QStyleSheet::mightBeRichText( t ) )
   520 		t = QStyleSheet::convertFromPlainText( t, QStyleSheetItem::WhiteSpaceNormal );
   521 	e->setReadOnly(false);
   522 	e->setText(t);
   523 	editorChanged();	//not called automagically
   524 
   525 	enableActions();
   526 }
   527 
   528 void TextEditor::setInactive()
   529 {
   530 	setText("");
   531 	state=inactiveEditor;
   532 	e->setPaper (inactivePaper);
   533 	e->setReadOnly (true);
   534 
   535 	disableActions();
   536 }
   537 
   538 void TextEditor::editCopyAll()
   539 {
   540 	e->selectAll();
   541 	e->copy();
   542 }
   543 
   544 void TextEditor::textSaveAs()
   545 {
   546     QString fn = QFileDialog::getSaveFileName( QString::null, "VYM Note (HTML) (*.html);;All files (*)",
   547 					       this,"export note dialog",tr("Export Note to single file") );
   548 
   549     if ( !fn.isEmpty() ) 
   550 	{
   551 		QFile file (fn);
   552 		if (file.exists())
   553 		{
   554 			QMessageBox mb( "VYM",
   555 				tr("The file ") + fn + 
   556 				tr(" exists already. "
   557 				"Do you want to overwrite it?"),
   558 			QMessageBox::Warning,
   559 			QMessageBox::Yes | QMessageBox::Default,
   560 			QMessageBox::Cancel | QMessageBox::Escape,
   561 			QMessageBox::NoButton );
   562 			mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
   563 			mb.setButtonText( QMessageBox::No, tr("Cancel"));
   564 			switch( mb.exec() ) {
   565 				case QMessageBox::Yes:
   566 					// save 
   567 					filename = fn;
   568 					textSave();
   569 					return;
   570 				case QMessageBox::Cancel:
   571 					// do nothing
   572 					break;
   573 			}
   574 		} else
   575 		{
   576 			filename = fn;
   577 			textSave();
   578 			return;
   579 		}			
   580     }
   581 	statusBar()->message(tr( "Couldn't export note ") + fn, statusbarTime );
   582 }
   583 
   584 
   585 void TextEditor::textSave()
   586 {
   587     if ( filename.isEmpty() ) 
   588 	{
   589 		textSaveAs();
   590 		return;
   591     }
   592 
   593     QString text = e->text();
   594     QFile f( filename );
   595     if ( !f.open( IO_WriteOnly ) ) 
   596 	{
   597 		statusBar()->message( QString("Could not write to %1").arg(filename),
   598 					  statusbarTime );
   599 		return;
   600     }
   601 
   602     QTextStream t( &f );
   603     t << text;
   604     f.close();
   605 
   606     e->setModified( FALSE );
   607 
   608     statusBar()->message( QString( "Note exported as %1" ).arg( filename ), statusbarTime );
   609 }
   610 
   611 void TextEditor::textConvertPar()
   612 {
   613 	// In X11 a copy&paste generates paragraphs, 
   614 	// which is not always wanted
   615 	// This function replaces paragraphs by linebreaks.
   616 	int parFrom, parTo, indFrom, indTo;
   617 	e->getSelection (&parFrom,&indFrom,&parTo,&indTo);
   618 	QString t;
   619 	if (parFrom>-1)
   620 		t=e->selectedText();
   621 	else
   622 		t=e->text();
   623 
   624 	QRegExp re("<p.*>");
   625 	re.setMinimal(true);
   626 	t.replace (re,"");
   627 	t.replace ("</p>","<br />");
   628 	if (parFrom>-1)
   629 	{
   630 		e->setCursorPosition (parFrom,indFrom);
   631 		e->cut();
   632 		// Tried to simply insert the changed text with
   633 		// e->insert (t,(uint)(QTextEdit::RemoveSelected));
   634 		// but then the html would be quoted. So I use the ugly
   635 		// way: insert a marker, replace it in whole text of QTextEdit
   636 		QString marker="R3PlAcEMeL4teR!";
   637 		e->insert (marker);
   638 		e->setText (e->text().replace(marker,t));
   639 	} else
   640 		e->setText(t);
   641 }
   642 
   643 void TextEditor::textJoinLines()
   644 {
   645 	int parFrom, parTo, indFrom, indTo;
   646 	e->getSelection (&parFrom,&indFrom,&parTo,&indTo);
   647 	QString t;
   648 	if (parFrom>-1)
   649 		t=e->selectedText();
   650 	else
   651 		t=e->text();
   652 	// In addition to textConvertPar it is sometimes
   653 	// useful to join all lines of a paragraph
   654 	QRegExp re("</p>\n+<p>(?!</p>)");
   655 	re.setMinimal(true);
   656 	t.replace (re," ");
   657 
   658 	// Above we may have introduced new " " at beginning of a
   659 	// paragraph - remove it.
   660 	re.setPattern("<p> ");
   661 	t.replace (re,"<p>");
   662 	if (parFrom>-1)
   663 	{
   664 		e->setCursorPosition (parFrom,indFrom);
   665 		e->cut();
   666 		// Tried to simply insert the changed text with
   667 		// e->insert (t,(uint)(QTextEdit::RemoveSelected));
   668 		// but then the html would be quoted. So I use the ugly
   669 		// way: insert a marker, replace it in whole text of QTextEdit
   670 		QString marker="R3PlAcEMeL4teR!";
   671 		e->insert (marker);
   672 		e->setText (e->text().replace(marker,t));
   673 	} else
   674 		e->setText(t);
   675 }
   676 
   677 QString TextEditor::textConvertToASCII(const QString &t)
   678 {
   679 	QString r=t;
   680 
   681 	// convert all "<br*>" to "\n"
   682 	QRegExp re("<br.*>");
   683 	re.setMinimal(true);
   684 	r.replace (re,"\n");
   685 
   686 	// convert all "</p>" to "\n"
   687 	re.setPattern ("/p");
   688 	r.replace (re,"\n");
   689 	
   690 	// remove all remaining tags 
   691 	re.setPattern ("<.*>");
   692 	r.replace (re,"");
   693 
   694 	// convert "&", "<" and ">"
   695 	re.setPattern ("&gt;");
   696 	r.replace (re,">");
   697 	re.setPattern ("&lt;");
   698 	r.replace (re,"<");
   699 	re.setPattern ("&amp;");
   700 	r.replace (re,"&");
   701 	return r;
   702 }
   703 
   704 void TextEditor::textExportAsASCII()
   705 {
   706 	QString text = textConvertToASCII( e->text());
   707 	QString fn,s;
   708 	if (!filenameHint.isEmpty())
   709 	{
   710 		if (!filenameHint.contains (".txt"))
   711 			s=filenameHint+".txt";
   712 		else	
   713 			s=filenameHint;
   714 	} else	
   715 		s=QString::null;
   716 	fn = QFileDialog::getSaveFileName( s, "VYM Note (ASCII) (*.txt);;All files (*)", this,"export note dialog",tr("Export Note to single file (ASCII)") );
   717 	int ret=-1;
   718 
   719     if ( !fn.isEmpty() ) 
   720 	{
   721 		QFile file (fn);
   722 		if (file.exists())
   723 		{
   724 			QMessageBox mb( "VYM",
   725 				tr("The file ") + fn + 
   726 				tr(" exists already. "
   727 				"Do you want to overwrite it?"),
   728 			QMessageBox::Warning,
   729 			QMessageBox::Yes | QMessageBox::Default,
   730 			QMessageBox::Cancel | QMessageBox::Escape,
   731 			QMessageBox::NoButton );
   732 			mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
   733 			mb.setButtonText( QMessageBox::No, tr("Cancel"));
   734 			ret=mb.exec();
   735 		}	
   736 		if (ret==QMessageBox::Cancel)
   737 			return;
   738 			
   739 		// save 
   740 		if ( !file.open( IO_WriteOnly ) ) 
   741 			statusBar()->message( QString("Could not write to %1").arg(filename),
   742 						  statusbarTime );
   743 		else
   744 		{
   745 			QTextStream t( &file );
   746 			t << text;
   747 			file.close();
   748 
   749 			statusBar()->message( QString( "Note exported as %1" ).arg( fn ), statusbarTime );
   750 		}
   751     }
   752 }
   753 
   754 
   755 void TextEditor::textPrint()
   756 {
   757     printer->setFullPage(TRUE);
   758     if ( printer->setup( this ) ) 
   759 	{
   760 		QPainter p( printer );
   761 		// Check that there is a valid device to print to.
   762 		if ( !p.device() ) return;
   763 		QPaintDeviceMetrics metrics( p.device() );
   764 		int dpiy = metrics.logicalDpiY();
   765 		int margin = (int) ( (2/2.54)*dpiy ); // 2 cm margins
   766 		QRect body( margin, margin, metrics.width() - 2*margin, metrics.height() - 2*margin );
   767 		QFont font( e->currentFont() );
   768 		font.setPointSize( 10 ); // we define 10pt to be a nice base size for printing
   769 
   770 		QSimpleRichText richText( e->text(), font,
   771 					  e->context(),
   772 					  e->styleSheet(),
   773 					  e->mimeSourceFactory(),
   774 					  body.height() );
   775 		richText.setWidth( &p, body.width() );
   776 		QRect view( body );
   777 		int page = 1;
   778 		do 
   779 		{
   780 			richText.draw( &p, body.left(), body.top(), view, colorGroup() );
   781 			view.moveBy( 0, body.height() );
   782 			p.translate( 0 , -body.height() );
   783 			p.setFont( font );
   784 			p.drawText( view.right() - p.fontMetrics().width( QString::number( page ) ),
   785 				view.bottom() + p.fontMetrics().ascent() + 5, QString::number( page ) );
   786 			if ( view.top()  >= richText.height() )
   787 			break;
   788 			printer->newPage();
   789 			page++;
   790 		} while (TRUE);
   791     }
   792 }
   793 
   794 void TextEditor::textEditUndo()
   795 {
   796 }
   797 
   798 void TextEditor::toggleFonthint()
   799 {
   800 	setUpdatesEnabled (false);
   801 	e->selectAll (true);
   802 	if (!actionFormatUseFixedFont->isOn() ) 
   803 		e->setCurrentFont (varFont);
   804 	else	
   805 		e->setCurrentFont (fixedFont);
   806 	e->selectAll (false);
   807 	setUpdatesEnabled (true);
   808 	repaint();
   809 }
   810 
   811 void TextEditor::setFixedFont()
   812 {
   813 	bool ok;
   814 	QFont font =QFontDialog::getFont(
   815                     &ok, fixedFont, this );
   816     if ( ok ) 
   817         // font is set to the font the user selected
   818 		fixedFont=font;
   819 }
   820 
   821 void TextEditor::setVarFont()
   822 {
   823 	bool ok;
   824 	QFont font =QFontDialog::getFont(
   825                     &ok, varFont, this );
   826     if ( ok ) 
   827         // font is set to the font the user selected
   828 		varFont=font;
   829 }
   830 
   831 void TextEditor::textBold()
   832 {
   833     e->setBold( actionTextBold->isOn() );
   834 }
   835 
   836 void TextEditor::textUnderline()
   837 {
   838     e->setUnderline( actionTextUnderline->isOn() );
   839 }
   840 
   841 void TextEditor::textItalic()
   842 {
   843     e->setItalic( actionTextItalic->isOn() );
   844 }
   845 
   846 void TextEditor::textFamily( const QString &f )
   847 {
   848     e->setFamily( f );
   849 }
   850 
   851 void TextEditor::textSize( const QString &p )
   852 {
   853     e->setPointSize( p.toInt() );
   854 }
   855 
   856 
   857 void TextEditor::textColor()
   858 {
   859     QColor col = QColorDialog::getColor( e->color(), this );
   860     if ( !col.isValid() )
   861 	return;
   862     e->setColor( col );
   863     QPixmap pix( 16, 16 );
   864     pix.fill( black );
   865     actionTextColor->setIconSet( pix );
   866 }
   867 
   868 void TextEditor::textAlign( QAction *a )
   869 {
   870     if ( a == actionAlignLeft )
   871 	e->setAlignment( AlignLeft );
   872     else if ( a == actionAlignCenter )
   873 	e->setAlignment( AlignHCenter );
   874     else if ( a == actionAlignRight )
   875 	e->setAlignment( AlignRight );
   876     else if ( a == actionAlignJustify )
   877 	e->setAlignment( AlignJustify );
   878 }
   879 
   880 void TextEditor::fontChanged( const QFont &f )
   881 {
   882     comboFont->lineEdit()->setText( f.family() );
   883     comboSize->lineEdit()->setText( QString::number( f.pointSize() ) );
   884     actionTextBold->setOn( f.bold() );
   885     actionTextItalic->setOn( f.italic() );
   886     actionTextUnderline->setOn( f.underline() );
   887 }
   888 
   889 void TextEditor::colorChanged( const QColor &c )
   890 {
   891     QPixmap pix( 16, 16 );
   892     pix.fill( c );
   893     actionTextColor->setIconSet( pix );
   894 }
   895 
   896 void TextEditor::alignmentChanged( int a )
   897 {
   898     if ( ( a == AlignAuto ) || ( a & AlignLeft ))
   899 	actionAlignLeft->setOn( true );
   900     else if ( ( a & AlignHCenter ) )
   901 	actionAlignCenter->setOn( true );
   902     else if ( ( a & AlignRight ) )
   903 	actionAlignRight->setOn( true );
   904     else if ( ( a & AlignJustify ) )
   905 	actionAlignJustify->setOn( true );
   906 }
   907 
   908 
   909 
   910 void TextEditor::enableActions()
   911 {
   912 	actionFileLoad->setEnabled(true);
   913 	actionFileSave->setEnabled(true);
   914 	actionFileSaveAs->setEnabled(true);
   915 	actionFilePrint->setEnabled(true);
   916 	actionEditUndo->setEnabled(true);
   917 	actionEditRedo->setEnabled(true);
   918 	actionEditCopy->setEnabled(true);
   919 	actionEditCut->setEnabled(true);
   920 	actionEditPaste->setEnabled(true);
   921 	actionEditDeleteAll->setEnabled(true);
   922 	actionEditConvertPar->setEnabled(true);
   923 	actionEditJoinLines->setEnabled(true);
   924 	actionFormatUseFixedFont->setEnabled(true);
   925 }
   926 
   927 void TextEditor::disableActions()
   928 {
   929 	actionFileLoad->setEnabled(false);
   930 	actionFileSave->setEnabled(false);
   931 	actionFileSaveAs->setEnabled(false);
   932 	actionFilePrint->setEnabled(false);
   933 	actionEditUndo->setEnabled(false);
   934 	actionEditRedo->setEnabled(false);
   935 	actionEditCopy->setEnabled(false);
   936 	actionEditCut->setEnabled(false);
   937 	actionEditPaste->setEnabled(false);
   938 	actionEditDeleteAll->setEnabled(false);
   939 	actionEditConvertPar->setEnabled(false);
   940 	actionEditJoinLines->setEnabled(false);
   941 	actionFormatUseFixedFont->setEnabled(false);
   942 }
   943 
   944