Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

mainwindow.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000-2002 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of the Qtopia Environment.
00005 **
00006 ** Licensees holding valid Qtopia Developer license may use this
00007 ** file in accordance with the Qtopia Developer License Agreement
00008 ** provided with the Software.
00009 **
00010 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
00011 ** THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00012 ** PURPOSE.
00013 **
00014 ** email sales@trolltech.com for information about Qtopia License
00015 ** Agreements.
00016 **
00017 ** Contact info@trolltech.com if any conditions of this licensing are
00018 ** not clear to you.
00019 **
00020 **********************************************************************/
00021 
00022 #include "mainwindow.h"
00023 
00024 /* OPIE */
00025 #include <opie2/odebug.h>
00026 #include <opie2/oresource.h>
00027 #include <qpe/fileselector.h>
00028 #include <qpe/applnk.h>
00029 #include <qpe/fontdatabase.h>
00030 using namespace Opie::Core;
00031 
00032 /* QT */
00033 #include "qtextedit.h"
00034 #include <qaction.h>
00035 #include <qtoolbar.h>
00036 #include <qtoolbutton.h>
00037 #include <qtabwidget.h>
00038 #include <qapplication.h>
00039 #include <qfontdatabase.h>
00040 #include <qcombobox.h>
00041 #include <qlineedit.h>
00042 #include <qfileinfo.h>
00043 #include <qfile.h>
00044 #include <qfiledialog.h>
00045 #include <qprinter.h>
00046 #include <qpaintdevicemetrics.h>
00047 #include <qmenubar.h>
00048 #include <qpopupmenu.h>
00049 #include <qcolordialog.h>
00050 #include <qpainter.h>
00051 #include <qstyle.h>
00052 
00053 class ButtonMenu : public QToolButton
00054 {
00055     Q_OBJECT
00056 public:
00057     ButtonMenu( QWidget *parent, const char *name=0 )
00058   : QToolButton( parent, name ), current(0)
00059     {
00060   setPopup( new QPopupMenu( this ) );
00061   setPopupDelay( 1 );
00062   connect( popup(), SIGNAL(activated(int)), this, SLOT(selected(int)) );
00063     }
00064 
00065     int insertItem(const QIconSet &icon, const QString &text, int id ) {
00066   if ( !popup()->count() ) {
00067       setIconSet( icon );
00068       current = id;
00069   }
00070   return popup()->insertItem( icon, text, id );
00071     }
00072 
00073     void setCurrentItem( int id ) {
00074   if ( id != current ) {
00075       current = id;
00076       setIconSet( *popup()->iconSet( id ) );
00077   }
00078     }
00079 
00080     virtual QSize sizeHint() const {
00081   return QToolButton::sizeHint() + QSize( 4, 0 );
00082     }
00083 
00084 signals:
00085     void activated( int id );
00086 
00087 protected slots:
00088     void selected( int id ) {
00089   current = id;
00090   setIconSet( *popup()->iconSet( id ) );
00091   emit activated( id );
00092     }
00093 
00094 protected:
00095     virtual void drawButtonLabel( QPainter *p ) {
00096   p->translate( -4, 0 );
00097   QToolButton::drawButtonLabel( p );
00098   p->translate( 4, 0 );
00099     }
00100 
00101 private:
00102     int current;
00103 };
00104 
00105 //===========================================================================
00106 
00107 MainWindow::MainWindow( QWidget *parent, const char *name, WFlags fl  )
00108     : QMainWindow( parent, name, fl ),
00109       doc( 0 )
00110 {
00111     setRightJustification(TRUE);
00112 
00113     editorStack = new QWidgetStack( this );
00114 
00115     fileSelector = new FileSelector( "text/html",
00116              editorStack, "fileselector" );
00117 
00118 
00119     fileSelector->setCloseVisible( FALSE );
00120     editorStack->addWidget( fileSelector, 0 );
00121 
00122     editor = new Qt3::QTextEdit( editorStack );
00123     editor->setTextFormat( Qt::RichText );
00124     editorStack->addWidget( editor, 1 );
00125 
00126     setupActions();
00127 
00128     QObject::connect( fileSelector, SIGNAL(closeMe()),
00129           this, SLOT(showEditTools()) );
00130     QObject::connect( fileSelector, SIGNAL(fileSelected(const DocLnk&)),
00131           this, SLOT(openFile(const DocLnk&)) );
00132     QObject::connect( fileSelector, SIGNAL(newSelected(const DocLnk&)),
00133           this, SLOT(newFile(const DocLnk&)) );
00134 
00135     if ( fileSelector->fileCount() < 1 )
00136   fileNew();
00137     else {
00138   fileOpen();
00139     }
00140     doConnections( editor );
00141 
00142     setCentralWidget( editorStack );
00143 }
00144 
00145 MainWindow::~MainWindow()
00146 {
00147     save();
00148 }
00149 
00150 void MainWindow::setupActions()
00151 {
00152     setToolBarsMovable(false);
00153 
00154     tbMenu = new QToolBar( this );
00155     tbMenu->setHorizontalStretchable( TRUE );
00156 
00157     QMenuBar *menu = new QMenuBar( tbMenu );
00158 
00159     tbEdit = new QToolBar( this );
00160 
00161     QPopupMenu *file = new QPopupMenu( this );
00162     menu->insertItem( tr("File"), file );
00163 
00164     QPopupMenu *edit = new QPopupMenu( this );
00165     menu->insertItem( tr("Edit"), edit );
00166 
00167     // ### perhaps these shortcut keys should have some
00168     //     IPaq keys defined???
00169     QAction *a;
00170 
00171     a = new QAction( tr( "New" ), Opie::Core::OResource::loadPixmap("new", Opie::Core::OResource::SmallIcon),
00172                      QString::null, 0, this, 0 );
00173     connect( a, SIGNAL(activated()), this, SLOT(fileNew()) );
00174     a->addTo( file );
00175 
00176     a = new QAction( tr( "Open" ), Opie::Core::OResource::loadPixmap( "fileopen", Opie::Core::OResource::SmallIcon ),
00177                      QString::null, 0, this, 0 );
00178     connect( a, SIGNAL(activated()), this, SLOT(fileOpen()) );
00179     a->addTo( file );
00180 
00181     a = new QAction( tr( "Undo" ), Opie::Core::OResource::loadPixmap("undo", Opie::Core::OResource::SmallIcon),
00182                      QString::null, 0, this, "editUndo" );
00183     connect( a, SIGNAL( activated() ), this, SLOT( editUndo() ) );
00184     connect( editor, SIGNAL(undoAvailable(bool)), a, SLOT(setEnabled(bool)) );
00185     a->addTo( tbEdit );
00186     a->addTo( edit );
00187     a = new QAction( tr( "Redo" ), Opie::Core::OResource::loadPixmap("redo", Opie::Core::OResource::SmallIcon),
00188          QString::null, 0, this, "editRedo" );
00189     connect( a, SIGNAL( activated() ), this, SLOT( editRedo() ) );
00190     connect( editor, SIGNAL(redoAvailable(bool)), a, SLOT(setEnabled(bool)) );
00191     a->addTo( tbEdit );
00192     a->addTo( edit );
00193 
00194     edit->insertSeparator();
00195 
00196     a = new QAction( tr( "Copy" ), Opie::Core::OResource::loadPixmap("copy", Opie::Core::OResource::SmallIcon ),
00197          QString::null, 0, this, "editCopy" );
00198     connect( a, SIGNAL( activated() ), this, SLOT( editCopy() ) );
00199     connect( editor, SIGNAL(copyAvailable(bool)), a, SLOT(setEnabled(bool)) );
00200     a->addTo( tbEdit );
00201     a->addTo( edit );
00202     a = new QAction( tr( "Cut" ), Opie::Core::OResource::loadPixmap("cut", Opie::Core::OResource::SmallIcon ),
00203          QString::null, 0, this, "editCut" );
00204     connect( a, SIGNAL( activated() ), this, SLOT( editCut() ) );
00205     connect( editor, SIGNAL(copyAvailable(bool)), a, SLOT(setEnabled(bool)) );
00206     a->addTo( tbEdit );
00207     a->addTo( edit );
00208     a = new QAction( tr( "Paste" ), Opie::Core::OResource::loadPixmap("paste", Opie::Core::OResource::SmallIcon ),
00209          QString::null, 0, this, "editPaste" );
00210     connect( a, SIGNAL( activated() ), this, SLOT( editPaste() ) );
00211     a->addTo( tbEdit );
00212     a->addTo( edit );
00213 
00214     tbFont = new QToolBar( this );
00215     tbFont->setLabel( "Font Actions" );
00216     tbFont->setHorizontalStretchable(TRUE);
00217 
00218     comboFont = new QComboBox( FALSE, tbFont );
00219     FontDatabase db;
00220     QStringList f= db.families();
00221     comboFont->insertStringList( db.families() );
00222     connect( comboFont, SIGNAL( activated(const QString&) ),
00223        this, SLOT( textFamily(const QString&) ) );
00224     comboFont->setCurrentItem( comboFont->listBox()->index( comboFont->listBox()->findItem( QApplication::font().family() ) ) );
00225     comboFont->setMaximumWidth(90);
00226 
00227     comboSize = new QComboBox( TRUE, tbFont );
00228     QValueList<int> sizes = db.standardSizes();
00229     QValueList<int>::Iterator it = sizes.begin();
00230     for ( ; it != sizes.end(); ++it )
00231   comboSize->insertItem( QString::number( *it ) );
00232     connect( comboSize, SIGNAL( activated(const QString&) ),
00233        this, SLOT( textSize(const QString&) ) );
00234     comboSize->lineEdit()->setText( QString::number( QApplication::font().pointSize() ) );
00235     comboSize->setFixedWidth( 38 );
00236 
00237     tbStyle = new QToolBar( this );
00238     tbStyle->setLabel( "Style Actions" );
00239 
00240     actionTextBold = new QAction( tr( "Bold" ),
00241                                   Opie::Core::OResource::loadPixmap("bold", Opie::Core::OResource::SmallIcon ),
00242                                   QString::null, CTRL + Key_B,
00243                                   this, "textBold" );
00244     connect( actionTextBold, SIGNAL( activated() ), this, SLOT( textBold() ) );
00245     actionTextBold->addTo( tbStyle );
00246     actionTextBold->setToggleAction( TRUE );
00247     actionTextItalic = new QAction( tr( "Italic" ),
00248                                     Opie::Core::OResource::loadPixmap("italic", Opie::Core::OResource::SmallIcon ),
00249                                     tr( "&Italic" ), CTRL + Key_I,
00250                                     this, "textItalic" );
00251     connect( actionTextItalic, SIGNAL( activated() ), this,
00252        SLOT( textItalic() ) );
00253     actionTextItalic->addTo( tbStyle );
00254     actionTextItalic->setToggleAction( TRUE );
00255     actionTextUnderline = new QAction( tr( "Underline" ),
00256                                        Opie::Core::OResource::loadPixmap("underline", Opie::Core::OResource::SmallIcon ),
00257                                        tr( "&Underline" ), CTRL + Key_U,
00258                                        this, "textUnderline" );
00259     connect( actionTextUnderline, SIGNAL( activated() ),
00260        this, SLOT( textUnderline() ) );
00261     actionTextUnderline->addTo( tbStyle );
00262     actionTextUnderline->setToggleAction( TRUE );
00263 
00264     alignMenu = new ButtonMenu( tbStyle );
00265     alignMenu->insertItem( Opie::Core::OResource::loadPixmap("left", Opie::Core::OResource::SmallIcon), tr("Left"), AlignLeft );
00266     alignMenu->insertItem( Opie::Core::OResource::loadPixmap("center", Opie::Core::OResource::SmallIcon),
00267                            tr("Center"), AlignCenter );
00268     alignMenu->insertItem( Opie::Core::OResource::loadPixmap("right", Opie::Core::OResource::SmallIcon),
00269                            tr("Right"), AlignRight );
00270     alignMenu->insertItem( Opie::Core::OResource::loadPixmap("opie-write/justify", Opie::Core::OResource::SmallIcon),
00271                            tr("Full"), Qt3::AlignJustify );
00272     connect( alignMenu, SIGNAL(activated(int)), this, SLOT(textAlign(int)) );
00273 }
00274 
00275 Qt3::QTextEdit *MainWindow::currentEditor() const
00276 {
00277     return editor;
00278 }
00279 
00280 void MainWindow::doConnections( Qt3::QTextEdit *e )
00281 {
00282     connect( e, SIGNAL( currentFontChanged(const QFont&) ),
00283        this, SLOT( fontChanged(const QFont&) ) );
00284     connect( e, SIGNAL( currentColorChanged(const QColor&) ),
00285        this, SLOT( colorChanged(const QColor&) ) );
00286     connect( e, SIGNAL( currentAlignmentChanged(int) ),
00287        this, SLOT( alignmentChanged(int) ) );
00288 }
00289 
00290 void MainWindow::updateFontSizeCombo( const QFont &f )
00291 {
00292     comboSize->clear();
00293     FontDatabase fdb;
00294     QValueList<int> sizes = fdb.pointSizes( f.family() );
00295     QValueList<int>::Iterator it = sizes.begin();
00296     for ( ; it != sizes.end(); ++it )
00297   comboSize->insertItem( QString::number( *it ) );
00298 }
00299 
00300 void MainWindow::editUndo()
00301 {
00302     if ( !currentEditor() )
00303   return;
00304     currentEditor()->undo();
00305 }
00306 
00307 void MainWindow::editRedo()
00308 {
00309     if ( !currentEditor() )
00310   return;
00311     currentEditor()->redo();
00312 }
00313 
00314 void MainWindow::editCut()
00315 {
00316     if ( !currentEditor() )
00317   return;
00318     currentEditor()->cut();
00319 }
00320 
00321 void MainWindow::editCopy()
00322 {
00323     if ( !currentEditor() )
00324   return;
00325     currentEditor()->copy();
00326 }
00327 
00328 void MainWindow::editPaste()
00329 {
00330     if ( !currentEditor() )
00331   return;
00332     currentEditor()->paste();
00333 }
00334 
00335 void MainWindow::textBold()
00336 {
00337     if ( !currentEditor() )
00338   return;
00339     currentEditor()->setBold( actionTextBold->isOn() );
00340 }
00341 
00342 void MainWindow::textUnderline()
00343 {
00344     if ( !currentEditor() )
00345   return;
00346     currentEditor()->setUnderline( actionTextUnderline->isOn() );
00347 }
00348 
00349 void MainWindow::textItalic()
00350 {
00351     if ( !currentEditor() )
00352   return;
00353     currentEditor()->setItalic( actionTextItalic->isOn() );
00354 }
00355 
00356 void MainWindow::textFamily( const QString &f )
00357 {
00358     if ( !currentEditor() )
00359   return;
00360     currentEditor()->setFamily( f );
00361     currentEditor()->viewport()->setFocus();
00362 }
00363 
00364 void MainWindow::textSize( const QString &p )
00365 {
00366     if ( !currentEditor() )
00367   return;
00368     currentEditor()->setPointSize( p.toInt() );
00369     currentEditor()->viewport()->setFocus();
00370 }
00371 
00372 void MainWindow::textStyle( int i )
00373 {
00374     if ( !currentEditor() )
00375   return;
00376     if ( i == 0 )
00377   currentEditor()->setParagType( Qt3::QStyleSheetItem::DisplayBlock,
00378                Qt3::QStyleSheetItem::ListDisc );
00379     else if ( i == 1 )
00380   currentEditor()->setParagType( Qt3::QStyleSheetItem::DisplayListItem,
00381                Qt3::QStyleSheetItem::ListDisc );
00382     else if ( i == 2 )
00383   currentEditor()->setParagType( Qt3::QStyleSheetItem::DisplayListItem,
00384                Qt3::QStyleSheetItem::ListCircle );
00385     else if ( i == 3 )
00386   currentEditor()->setParagType( Qt3::QStyleSheetItem::DisplayListItem,
00387                Qt3::QStyleSheetItem::ListSquare );
00388     else if ( i == 4 )
00389   currentEditor()->setParagType( Qt3::QStyleSheetItem::DisplayListItem,
00390                Qt3::QStyleSheetItem::ListDecimal );
00391     else if ( i == 5 )
00392   currentEditor()->setParagType( Qt3::QStyleSheetItem::DisplayListItem,
00393                Qt3::QStyleSheetItem::ListLowerAlpha );
00394     else if ( i == 6 )
00395   currentEditor()->setParagType( Qt3::QStyleSheetItem::DisplayListItem,
00396                Qt3::QStyleSheetItem::ListUpperAlpha );
00397     currentEditor()->viewport()->setFocus();
00398 }
00399 
00400 void MainWindow::textAlign( int a )
00401 {
00402     if ( !currentEditor() )
00403   return;
00404     editor->setAlignment( a );
00405 }
00406 
00407 void MainWindow::fontChanged( const QFont &f )
00408 {
00409     comboFont->setCurrentItem( comboFont->listBox()->index( comboFont->listBox()->findItem( f.family() ) ) );
00410     updateFontSizeCombo( f );
00411     comboSize->lineEdit()->setText( QString::number( f.pointSize() ) );
00412     actionTextBold->setOn( f.bold() );
00413     actionTextItalic->setOn( f.italic() );
00414     actionTextUnderline->setOn( f.underline() );
00415 }
00416 
00417 void MainWindow::colorChanged( const QColor & )
00418 {
00419 }
00420 
00421 void MainWindow::alignmentChanged( int a )
00422 {
00423     if ( ( a == Qt3::AlignAuto ) || ( a & AlignLeft )) {
00424   alignMenu->setCurrentItem(AlignLeft);
00425     } else if ( ( a & AlignCenter ) ) {
00426   alignMenu->setCurrentItem(AlignCenter);
00427     } else if ( ( a & AlignRight ) ) {
00428   alignMenu->setCurrentItem(AlignRight);
00429     } else if ( ( a & Qt3::AlignJustify ) ) {
00430   alignMenu->setCurrentItem(Qt3::AlignJustify);
00431     }
00432 }
00433 
00434 void MainWindow::editorChanged( QWidget * )
00435 {
00436     if ( !currentEditor() )
00437   return;
00438     fontChanged( currentEditor()->font() );
00439     colorChanged( currentEditor()->color() );
00440     alignmentChanged( currentEditor()->alignment() );
00441 }
00442 
00443 void MainWindow::fileOpen()
00444 {
00445     save();
00446     editorStack->raiseWidget( fileSelector );
00447     fileSelector->reread();
00448     hideEditTools();
00449     fileSelector->setNewVisible( TRUE );
00450     clear();
00451     updateCaption();
00452 }
00453 
00454 void MainWindow::fileRevert()
00455 {
00456     odebug << "QMainWindow::fileRevert needs to be done" << oendl; 
00457 }
00458 
00459 void MainWindow::fileNew()
00460 {
00461     editor->setTextFormat( Qt::RichText );
00462     save();
00463     newFile(DocLnk());
00464 }
00465 
00466 void MainWindow::insertTable()
00467 {
00468     odebug << "MainWindow::insertTable() needs to be done" << oendl; 
00469 }
00470 
00471 void MainWindow::newFile( const DocLnk &dl )
00472 {
00473     DocLnk nf = dl;
00474     nf.setType( "text/html" );
00475     clear();
00476     editorStack->raiseWidget( editor );
00477     editor->viewport()->setFocus();
00478     doc = new DocLnk( nf );
00479     updateCaption();
00480 }
00481 
00482 void MainWindow::openFile( const DocLnk &dl )
00483 {
00484     FileManager fm;
00485     QString txt;
00486     if ( !fm.loadFile( dl, txt ) )
00487   odebug << "couldn't open file" << oendl; 
00488     clear();
00489     editorStack->raiseWidget( editor );
00490     editor->viewport()->setFocus();
00491     doc = new DocLnk( dl );
00492     editor->setText( txt );
00493     editor->setModified( FALSE );
00494     updateCaption();
00495 }
00496 
00497 void MainWindow::showEditTools( void )
00498 {
00499     tbMenu->show();
00500     tbEdit->show();
00501     tbFont->show();
00502     tbStyle->show();
00503 }
00504 
00505 void MainWindow::hideEditTools( void )
00506 {
00507     // let's reset the buttons...
00508     actionTextBold->setOn( FALSE );
00509     actionTextItalic->setOn( FALSE );
00510     actionTextUnderline->setOn( FALSE );
00511     //comboFont->setCurrentText( QApplication::font().family() );
00512     comboSize->lineEdit()->setText( QString::number(QApplication::font().pointSize() ) );
00513     tbMenu->hide();
00514     tbEdit->hide();
00515     tbFont->hide();
00516     tbStyle->hide();
00517 }
00518 
00519 
00520 void MainWindow::save()
00521 {
00522     if ( !doc )
00523   return;
00524     if ( !editor->isModified() )
00525   return;
00526 
00527     QString rt = editor->text();
00528 
00529     // quick hack to get around formatting...
00530     editor->setTextFormat( Qt::PlainText );
00531     QString pt = editor->text();
00532     editor->setTextFormat( Qt::RichText );
00533 
00534     if ( doc->name().isEmpty() ) {
00535   unsigned ispace = pt.find( ' ' );
00536   unsigned ienter = pt.find( '\n' );
00537   int i = (ispace < ienter) ? ispace : ienter;
00538   QString docname;
00539   if ( i == -1 ) {
00540       if ( pt.isEmpty() )
00541     docname = "Empty Text";
00542       else
00543     docname = pt;
00544   } else {
00545       docname = pt.left( i );
00546   }
00547   doc->setName(docname);
00548     }
00549     FileManager fm;
00550     fm.saveFile( *doc, rt );
00551 }
00552 
00553 void MainWindow::clear()
00554 {
00555     delete doc;
00556     doc = 0;
00557     editor->clear();
00558 }
00559 
00560 void MainWindow::updateCaption()
00561 {
00562     if ( !doc )
00563   setCaption( tr("Rich Text Editor") );
00564     else {
00565   QString s = doc->name();
00566   if ( s.isEmpty() )
00567       s = tr( "Unnamed" );
00568   setCaption( s + " - " + tr("Rich Text Editor") );
00569     }
00570 }
00571 
00572 void MainWindow::closeEvent( QCloseEvent *e )
00573 {
00574     if ( editorStack->visibleWidget() == editor ) {
00575   // call fileOpen instead, don't close it
00576   fileOpen();
00577   e->ignore();
00578     } else {
00579   e->accept();
00580     }
00581 }
00582 
00583 #include "mainwindow.moc"

Generated on Sat Nov 5 16:15:51 2005 for OPIE by  doxygen 1.4.2