F:/KPlato/koffice/kplato/kptpart.cc

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002  Copyright (C) 1998, 1999, 2000 Torben Weis <weis@kde.org>
00003  Copyright (C) 2004, 2005 Dag Andersen <danders@get2net.dk>
00004  Copyright (C) 2006 Raphael Langerhorst <raphael.langerhorst@kdemail.net>
00005 
00006  This library is free software; you can redistribute it and/or
00007  modify it under the terms of the GNU Library General Public
00008  License as published by the Free Software Foundation; either
00009  version 2 of the License, or (at your option) any later version.
00010 
00011  This library is distributed in the hope that it will be useful,
00012  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  Library General Public License for more details.
00015 
00016  You should have received a copy of the GNU Library General Public License
00017  along with this library; see the file COPYING.LIB.  If not, write to
00018  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019 * Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "kptpart.h"
00023 #include "kptview.h"
00024 #include "kptfactory.h"
00025 #include "kptproject.h"
00026 #include "kptmainprojectdialog.h"
00027 #include "kptresource.h"
00028 #include "kptcontext.h"
00029 #include "kptganttview.h"
00030 #include "KDGanttViewTaskLink.h"
00031 
00032 #include <qpainter.h>
00033 #include <qfileinfo.h>
00034 #include <QTimer>
00035 
00036 #include <kdebug.h>
00037 #include <kconfig.h>
00038 #include <klocale.h>
00039 #include <kmessagebox.h>
00040 #include <kstandarddirs.h>
00041 #include <kcommand.h>
00042 #include <kcommand.h>
00043 #include <KoGlobal.h>
00044 
00045 #define CURRENT_SYNTAX_VERSION "0.5"
00046 
00047 namespace KPlato
00048 {
00049 
00050 Part::Part( QWidget *parentWidget, QObject *parent, bool singleViewMode )
00051         : KoDocument( parentWidget, parent, singleViewMode ),
00052         m_project( 0 ), m_projectDialog( 0 ), m_parentWidget( parentWidget ), m_view( 0 ),
00053         m_embeddedGanttView( 0 ),  //new GanttView(parentWidget)),
00054         m_embeddedContext( 0 ),  //new Context()), m_embeddedContextInitialized(false),
00055         m_context( 0 ), m_xmlLoader()
00056 {
00057     m_update = m_calculate = false;
00058     m_commandHistory = new KCommandHistory( actionCollection() );
00059 
00060     setInstance( Factory::global() );
00061     setTemplateType( "kplato_template" );
00062     m_config.setReadWrite( isReadWrite() || !isEmbedded() );
00063     m_config.load();
00064 
00065     delete m_project;
00066     m_project = new Project(); // after config is loaded
00067 
00068     connect( m_commandHistory, SIGNAL( commandExecuted( KCommand * ) ), SLOT( slotCommandExecuted( KCommand * ) ) );
00069     connect( m_commandHistory, SIGNAL( documentRestored() ), SLOT( slotDocumentRestored() ) );
00070 
00071     //FIXME the following is really dirty, we should make KPlato::Context a real class
00072     //      with getter and setter and signals when content changes, thus we can keep track
00073     QTimer* timer = new QTimer( this, "context update timer" );
00074     connect( timer, SIGNAL( timeout() ), this, SLOT( slotCopyContextFromView() ) );
00075     timer->start( 500 );
00076 }
00077 
00078 
00079 Part::~Part()
00080 {
00081     m_config.save();
00082     delete m_commandHistory; // before project, in case of dependencies...
00083     delete m_project;
00084     delete m_projectDialog;
00085     if ( m_embeddedGanttView )
00086         delete m_embeddedGanttView;
00087     if ( m_embeddedContext )
00088         delete m_embeddedContext;
00089 }
00090 
00091 
00092 KoView *Part::createViewInstance( QWidget *parent )
00093 {
00094     m_view = new View( this, parent );
00095     connect( m_view, SIGNAL( destroyed() ), this, SLOT( slotViewDestroyed() ) );
00096 
00097     // If there is a project dialog this should be deleted so it will
00098     // use the m_view as parent. If the dialog will be needed again,
00099     // it will be made at that point
00100     if ( m_projectDialog != 0 ) {
00101         kDebug() << "Deleting m_projectDialog because of new ViewInstance\n";
00102         delete m_projectDialog;
00103         m_projectDialog = 0;
00104     }
00105     if ( m_context )
00106         m_view->setContext( *m_context );
00107     else if ( m_embeddedContext && m_embeddedContextInitialized )
00108         m_view->setContext( *m_embeddedContext );
00109     else {
00110         // Activate menu actions. Assumes ganttview, we don't get any
00111         // 'aboutToShow' signal. Need to redo action control.
00112         m_view->setTaskActionsEnabled( true );
00113     }
00114     //m_view->setBaselineMode(getProject().isBaselined()); FIXME: Removed for this release
00115     return m_view;
00116 }
00117 
00118 
00119 void Part::editProject()
00120 {
00121 
00122     QWidget * parent = m_parentWidget;
00123     if ( m_view )
00124         parent = m_view;
00125 
00126     if ( m_projectDialog == 0 )
00127         // Make the dialog
00128         m_projectDialog = new MainProjectDialog( *m_project, parent );
00129 
00130     m_projectDialog->exec();
00131 }
00132 
00133 
00134 bool Part::loadXML( QIODevice *, const QDomDocument &document )
00135 {
00136     QTime dt;
00137     dt.start();
00138     emit sigProgress( 0 );
00139 
00140     QString value;
00141     QDomElement plan = document.documentElement();
00142 
00143     // Check if this is the right app
00144     value = plan.attribute( "mime", QString::null );
00145     if ( value.isEmpty() ) {
00146         kError() << "No mime type specified!" << endl;
00147         setErrorMessage( i18n( "Invalid document. No mimetype specified." ) );
00148         return false;
00149     } else if ( value != "application/x-vnd.kde.kplato" ) {
00150         kError() << "Unknown mime type " << value << endl;
00151         setErrorMessage( i18n( "Invalid document. Expected mimetype application/x-vnd.kde.kplato, got %1", value ) );
00152         return false;
00153     }
00154     QString m_syntaxVersion = plan.attribute( "version", CURRENT_SYNTAX_VERSION );
00155     if ( m_syntaxVersion > CURRENT_SYNTAX_VERSION ) {
00156         int ret = KMessageBox::warningContinueCancel(
00157                       0, i18n( "This document was created with a newer version of KPlato (syntax version: %1)\n"
00158                                "Opening it in this version of KPlato will lose some information.", m_syntaxVersion ),
00159                       i18n( "File-Format Mismatch" ), KGuiItem( i18n( "Continue" ) ) );
00160         if ( ret == KMessageBox::Cancel ) {
00161             setErrorMessage( "USER_CANCELED" );
00162             return false;
00163         }
00164     }
00165     emit sigProgress( 5 );
00166 
00167     QDomNodeList list = plan.childNodes();
00168     if ( list.count() > 2 ) {
00169         // TODO: Make a proper bitching about this
00170         kDebug() << "*** Error ***\n";
00171         kDebug() << "  Children count should be 1 but is " << list.count()
00172         << "\n";
00173         return false;
00174     }
00175     m_xmlLoader.startLoad();
00176     for ( unsigned int i = 0; i < list.count(); ++i ) {
00177         if ( list.item( i ).isElement() ) {
00178             QDomElement e = list.item( i ).toElement();
00179 
00180             if ( e.tagName() == "context" ) {
00181                 delete m_context;
00182                 m_context = new Context();
00183                 m_context->load( e );
00184             } else if ( e.tagName() == "project" ) {
00185                 Project * newProject = new Project();
00186                 if ( newProject->load( e ) ) {
00187                     // The load went fine. Throw out the old project
00188                     delete m_project;
00189                     m_project = newProject;
00190                     delete m_projectDialog;
00191                     m_projectDialog = 0;
00192                 } else {
00193                     delete newProject;
00194                     m_xmlLoader.addMsg( XMLLoaderObject::Errors, "Loading of project failed" );
00195                     //TODO add some ui here
00196                 }
00197             }
00198         }
00199     }
00200     m_xmlLoader.stopLoad();
00201     emit sigProgress( 100 ); // the rest is only processing, not loading
00202 
00203     kDebug() << "Loading took " << ( float ) ( dt.elapsed() ) / 1000 << " seconds" << endl;
00204 
00205     // do some sanity checking on document.
00206     emit sigProgress( -1 );
00207 
00208     m_commandHistory->clear();
00209     m_commandHistory->documentSaved();
00210     setModified( false );
00211     if ( m_view )
00212         m_view->slotUpdate( false );
00213     return true;
00214 }
00215 
00216 QDomDocument Part::saveXML()
00217 {
00218     QDomDocument document( "kplato" );
00219 
00220     document.appendChild( document.createProcessingInstruction(
00221                               "xml",
00222                               "version=\"1.0\" encoding=\"UTF-8\"" ) );
00223 
00224     QDomElement doc = document.createElement( "kplato" );
00225     doc.setAttribute( "editor", "KPlato" );
00226     doc.setAttribute( "mime", "application/x-vnd.kde.kplato" );
00227     doc.setAttribute( "version", CURRENT_SYNTAX_VERSION );
00228     document.appendChild( doc );
00229 
00230     delete m_context;
00231     m_context = 0;
00232     if ( m_view ) {
00233         m_context = new Context();
00234         m_view->getContext( *m_context );
00235     }
00236     if ( m_context ) {
00237         m_context->save( doc );
00238     }
00239     // Save the project
00240     m_project->save( doc );
00241 
00242     m_commandHistory->documentSaved();
00243     return document;
00244 }
00245 
00246 
00247 void Part::slotDocumentRestored()
00248 {
00249     //kDebug()<<k_funcinfo<<endl;
00250     setModified( false );
00251 }
00252 
00253 
00254 void Part::paintContent( QPainter &painter, const QRect &rect,
00255                          bool /*transparent*/,
00256                          double zoomX, double /*zoomY*/ )
00257 {
00258     kDebug() << "----------- KPlato: Part::paintContent ------------" << endl;
00259     if ( isEmbedded() && m_embeddedGanttView && m_project ) {
00260         if ( m_embeddedContext ) {
00261             int ganttsize = m_embeddedContext->ganttview.ganttviewsize;
00262             int tasksize = m_embeddedContext->ganttview.taskviewsize;
00263             bool showtaskname = m_embeddedContext->ganttview.showTaskName;
00264 
00265             //            m_embeddedContext->ganttview.ganttviewsize += m_embeddedContext->ganttview.taskviewsize;
00266             //            m_embeddedContext->ganttview.taskviewsize = 0;  //TODO this doesn't have any effect?! (bug?)
00267             m_embeddedContext->ganttview.showTaskName = true;  //since task view is not shown(?), show name in the gantt itself
00268 
00269             m_embeddedGanttView->setContext( m_embeddedContext->ganttview, *m_project );
00270 
00271             m_embeddedContext->ganttview.ganttviewsize = ganttsize;
00272             m_embeddedContext->ganttview.taskviewsize = tasksize;
00273             m_embeddedContext->ganttview.showTaskName = showtaskname;
00274         } else {
00275             kWarning() << "Don't have any context to set!" << endl;
00276         }
00277         painter.setClipRect( rect );
00278         // We don't support zoom yet, so use the painters scaling
00279         double d_zoom = 1.0;
00280         setZoomAndResolution( 100, KoGlobal::dpiX(), KoGlobal::dpiY() );
00281         if ( m_zoomedResolutionX != zoomX ) {
00282             d_zoom *= ( zoomX / m_zoomedResolutionX );
00283             painter.scale( d_zoom, d_zoom );
00284         }
00285 
00286         m_embeddedGanttView->clear();
00287         m_embeddedGanttView->draw( *m_project );
00288         m_embeddedGanttView->drawOnPainter( &painter, rect );
00289     }
00290     // ####### handle transparency
00291 
00292     // Need to draw only the document rectangle described in the parameter rect.
00293     //     int left = rect.left() / 20;
00294     //     int right = rect.right() / 20 + 1;
00295     //     int top = rect.top() / 20;
00296     //     int bottom = rect.bottom() / 20 + 1;
00297 
00298     //     for( int x = left; x < right; ++x )
00299     //         painter.drawLine( x * 40, top * 20, 40 * 20, bottom * 20 );
00300     //     for( int y = left; y < right; ++y )
00301     //         painter.drawLine( left * 20, y * 20, right * 20, y * 20 );
00302 }
00303 
00304 
00305 void Part::addCommand( KCommand * cmd, bool execute )
00306 {
00307     m_commandHistory->addCommand( cmd, execute );
00308 }
00309 
00310 void Part::slotCommandExecuted( KCommand * )
00311 {
00312     //kDebug()<<k_funcinfo<<endl;
00313     setModified( true );
00314     kDebug() << "------- KPlato, is embedded: " << isEmbedded() << endl;
00315     if ( m_view == NULL )
00316         return ;
00317 
00318     if ( m_calculate )
00319         m_view->slotUpdate( false /*config().behavior().calculationMode == Behavior::OnChange*/ );
00320     else if ( m_update )
00321         m_view->slotUpdate( false );
00322 
00323     m_update = m_calculate = false;
00324 }
00325 
00326 void Part::slotCopyContextFromView()
00327 {
00328     if ( m_view && m_embeddedContext ) {
00329         //         kDebug() << "Updating embedded context from view context." << endl;
00330         this->m_view->getContext( *m_embeddedContext );
00331         this->m_embeddedContextInitialized = true;
00332     }
00333     //     else
00334     //     {
00335     //         kDebug() << "Not updating the context." << endl;
00336     //         if (m_context)
00337     //           kDebug() << "Current View: " << m_context->currentView << endl;
00338     //     }
00339 }
00340 
00341 void Part::slotViewDestroyed()
00342 {
00343     m_view = NULL;
00344 }
00345 
00346 void Part::setCommandType( int type )
00347 {
00348     //kDebug()<<k_funcinfo<<"type="<<type<<endl;
00349     if ( type == 0 )
00350         m_update = true;
00351     else if ( type == 1 )
00352         m_calculate = true;
00353 }
00354 
00355 void Part::generateWBS()
00356 {
00357     m_project->generateWBS( 1, m_wbsDefinition );
00358 }
00359 
00360 }  //KPlato namespace
00361 
00362 #include "kptpart.moc"

Généré le Wed Nov 22 23:40:57 2006 pour KPlato par  doxygen 1.5.1-p1