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