[Korganizer-devel] [Bug 123350] Kontact crashes if you click "OK" before completing "Resourse Selection"

Reinhold Kainhofer reinhold at kainhofer.com
Wed Jan 10 23:02:41 CET 2007


------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
         
http://bugs.kde.org/show_bug.cgi?id=123350         
reinhold kainhofer com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED



------- Additional Comments From reinhold kainhofer com  2007-01-10 23:02 -------
SVN commit 622165 by kainhofe:

Add the ability to the CalendarResource to set a parent widget for dialogs like the resource selection dialog. This is used in KOrganizer to make sure that the resource selection dialog is a child of the editor dialog (and thus disables the editor dialog).

This also fixes the crash described in bug 123350.

BUG: 123350


 M  +9 -7      korganizer/calendarview.cpp  
 M  +4 -0      korganizer/history.cpp  
 M  +20 -4     korganizer/incidencechanger.cpp  
 M  +1 -1      korganizer/incidencechanger.h  
 M  +2 -1      korganizer/interfaces/korganizer/incidencechangerbase.h  
 M  +1 -1      korganizer/journalentry.cpp  
 M  +2 -2      korganizer/koagenda.cpp  
 M  +1 -1      korganizer/koagendaview.cpp  
 M  +1 -1      korganizer/koeventeditor.cpp  
 M  +1 -1      korganizer/kojournaleditor.cpp  
 M  +1 -1      korganizer/kotodoeditor.cpp  
 M  +3 -3      korganizer/kotodoview.cpp  
 M  +11 -1     libkcal/calendarresources.cpp  
 M  +27 -7     libkcal/calendarresources.h  
 M  +1 -0      libkdepim/kdateedit.cpp  


--- branches/KDE/3.5/kdepim/korganizer/calendarview.cpp #622164:622165
 @ -708,7 +708,7  @
           journal->setSummary( i18n("Journal of %1").arg( dateStr ) );
           journal->setDescription( description );
 
-          if ( !mChanger->addIncidence( journal ) ) {
+          if ( !mChanger->addIncidence( journal, this ) ) {
             KODialogManager::errorSaveIncidence( this, journal );
             delete journal;
             return;
 @ -892,14 +892,14  @
         pastedEvent->setDtEnd(endDT);
       }
     }
-    mChanger->addIncidence( pastedEvent );
+    mChanger->addIncidence( pastedEvent, this );
 
   } else if ( pastedIncidence->type() == "Todo" ) {
     Todo* pastedTodo = static_cast<Todo*>(pastedIncidence);
     Todo* _selectedTodo = selectedTodo();
     if ( _selectedTodo )
       pastedTodo->setRelatedTo( _selectedTodo );
-    mChanger->addIncidence( pastedTodo );
+    mChanger->addIncidence( pastedTodo, this );
   }
 }
 
 @ -1080,7 +1080,7  @
   format.setTimeZone( mCalendar->timeZoneId(), true );
   Incidence *incidence = format.fromString( ical );
   if ( !incidence ) return false;
-  if ( !mChanger->addIncidence( incidence ) ) {
+  if ( !mChanger->addIncidence( incidence, this ) ) {
     delete incidence;
     return false;
   }
 @ -1233,8 +1233,9  @
   Incidence* newInc = mCalendar->dissociateOccurrence( incidence, date, true );
 
   if ( newInc ) {
+    // TODO: Use the same resource instead of asking again!
     mChanger->changeIncidence( oldincidence, incidence );
-    mChanger->addIncidence( newInc );
+    mChanger->addIncidence( newInc, this );
   } else {
     KMessageBox::sorry( this, i18n("Dissociating the occurrence failed."),
       i18n("Dissociating Failed") );
 @ -1259,8 +1260,9  @
 
   Incidence* newInc = mCalendar->dissociateOccurrence( incidence, date, true );
   if ( newInc ) {
+    // TODO: Use the same resource instead of asking again!
     mChanger->changeIncidence( oldincidence, incidence );
-    mChanger->addIncidence( newInc );
+    mChanger->addIncidence( newInc, this );
   } else {
     KMessageBox::sorry( this, i18n("Dissociating the future occurrences failed."),
       i18n("Dissociating Failed") );
 @ -2184,7 +2186,7  @
     todo->setHasDueDate( true );
   }
 
-  if ( !mChanger->addIncidence( incidence ) ) {
+  if ( !mChanger->addIncidence( incidence, this ) ) {
     KODialogManager::errorSaveIncidence( this, incidence );
     delete incidence;
   }
--- branches/KDE/3.5/kdepim/korganizer/history.cpp #622164:622165
 @ -170,6 +170,7  @
 
 void History::EntryDelete::undo()
 {
+  // TODO: Use the proper resource instead of asking!
   mCalendar->addIncidence( mIncidence->clone() );
 }
 
 @ -204,6 +205,7  @
 
 void History::EntryAdd::redo()
 {
+  // TODO: User the proper resource instead of asking again
   mCalendar->addIncidence( mIncidence->clone() );
 }
 
 @ -231,6 +233,7  @
   Incidence *incidence = mCalendar->incidence( mNewIncidence->uid() );
   if ( incidence )
       mCalendar->deleteIncidence( incidence );
+  // TODO: Use the proper resource instead of asking again
   mCalendar->addIncidence( mOldIncidence->clone() );
 }
 
 @ -239,6 +242,7  @
   Incidence *incidence = mCalendar->incidence( mOldIncidence->uid() );
   if ( incidence )
       mCalendar->deleteIncidence( incidence );
+  // TODO: Use the proper resource instead of asking again
   mCalendar->addIncidence( mNewIncidence->clone() );
 }
 
--- branches/KDE/3.5/kdepim/korganizer/incidencechanger.cpp #622164:622165
 @ -288,18 +288,34  @
   return true;
 }
 
-bool IncidenceChanger::addIncidence( Incidence *incidence )
+bool IncidenceChanger::addIncidence( Incidence *incidence, QWidget *parent )
 {
 kdDebug(5850)<<"IncidenceChanger::addIncidence for incidence \""<<incidence->summary()<<"\""<<endl;
   if ( KOPrefs::instance()->mUseGroupwareCommunication ) {
-    if ( !KOGroupware::instance()->sendICalMessage( 0,
+    if ( !KOGroupware::instance()->sendICalMessage( parent,
                                                     KCal::Scheduler::Request,
                                                     incidence ) ) {
       kdError() << "sendIcalMessage failed." << endl;
     }
   }
-  if ( !mCalendar->addIncidence( incidence ) ) {
-    KMessageBox::sorry( 0, i18n("Unable to save %1 \"%2\".")
+  // FIXME: This is a nasty hack, since we need to set a parent for the 
+  //        resource selection dialog. However, we don't have any UI methods
+  //        in the calendar, only in the CalendarResources::DestinationPolicy
+  //        So we need to type-cast it and extract it from the CalendarResources
+  CalendarResources *stdcal = dynamic_cast<CalendarResources*>(mCalendar);
+  QWidget *tmpparent = 0;
+  if ( stdcal ) {
+    tmpparent = stdcal->dialogParentWidget();
+    stdcal->setDialogParentWidget( parent );
+  }
+  bool success = mCalendar->addIncidence( incidence );
+  if ( stdcal ) {
+    // Reset the parent widget, otherwise we'll end up with pointers to deleted 
+    // widgets sooner or later
+    stdcal->setDialogParentWidget( tmpparent );
+  }
+  if ( !success ) {
+    KMessageBox::sorry( parent, i18n("Unable to save %1 \"%2\".")
                         .arg( i18n( incidence->type() ) )
                         .arg( incidence->summary() ) );
     return false;
--- branches/KDE/3.5/kdepim/korganizer/incidencechanger.h #622164:622165
 @ -37,7 +37,7  @
   bool sendGroupwareMessage( Incidence *incidence, KCal::Scheduler::Method method, bool deleting = false );
   bool endChange( Incidence *incidence );
 
-  bool addIncidence( Incidence *incidence );
+  bool addIncidence( Incidence *incidence, QWidget *parent = 0 );
   bool changeIncidence( Incidence *oldinc, Incidence *newinc, int action = -1 );
   bool deleteIncidence( Incidence *incidence );
   
--- branches/KDE/3.5/kdepim/korganizer/interfaces/korganizer/incidencechangerbase.h #622164:622165
 @ -24,6 +24,7  @
 #include <libkcal/scheduler.h>
 #include <qobject.h>
 
+class QWidget;
 namespace KCal {
 class Calendar;
 class Incidence;
 @ -46,7 +47,7  @
   virtual bool beginChange( Incidence * incidence ) = 0;
   virtual bool endChange( Incidence *incidence ) = 0;
 
-  virtual bool addIncidence( Incidence *incidence ) = 0;
+  virtual bool addIncidence( Incidence *incidence, QWidget *parent = 0 ) = 0;
   virtual bool changeIncidence( Incidence *newinc, Incidence *oldinc, 
                                 int action = -1 ) = 0;
   virtual bool deleteIncidence( Incidence *incidence ) = 0;
--- branches/KDE/3.5/kdepim/korganizer/journalentry.cpp #622164:622165
 @ -383,7 +383,7  @
     newJournal = true;
     mJournal = new Journal;
     writeJournalPrivate( mJournal );
-    if ( !mChanger->addIncidence( mJournal ) ) {
+    if ( !mChanger->addIncidence( mJournal, this ) ) {
       KODialogManager::errorSaveIncidence( this, mJournal );
       delete mJournal;
       mJournal = 0;
--- branches/KDE/3.5/kdepim/korganizer/koagenda.cpp #622164:622165
 @ -1078,7 +1078,7  @
               emit enableAgendaUpdate( false );
               mActionItem->dissociateFromMultiItem();
               mActionItem->setIncidence( newInc );
-              mChanger->addIncidence( newInc );
+              mChanger->addIncidence( newInc, this );
               emit enableAgendaUpdate( true );
               mChanger->changeIncidence( oldIncSaved, oldInc );
             } else {
 @ -1105,7 +1105,7  @
               emit enableAgendaUpdate( false );
               mActionItem->dissociateFromMultiItem();
               mActionItem->setIncidence( newInc );
-              mChanger->addIncidence( newInc );
+              mChanger->addIncidence( newInc, this );
               emit enableAgendaUpdate( true );
               mChanger->changeIncidence( oldIncSaved, oldInc );
             } else {
--- branches/KDE/3.5/kdepim/korganizer/koagendaview.cpp #622164:622165
 @ -1570,7 +1570,7  @
       todo->setDtDue( newTime );
       todo->setFloats( allDay );
       todo->setHasDueDate( true );
-      if ( !mChanger->addIncidence( todo ) ) {
+      if ( !mChanger->addIncidence( todo, this ) ) {
         KODialogManager::errorSaveIncidence( this, todo );
       }
     }
--- branches/KDE/3.5/kdepim/korganizer/koeventeditor.cpp #622164:622165
 @ -277,7 +277,7  @
     mEvent->setOrganizer( Person( KOPrefs::instance()->fullName(),
                           KOPrefs::instance()->email() ) );
     writeEvent( mEvent );
-    if ( !mChanger->addIncidence( mEvent ) ) {
+    if ( !mChanger->addIncidence( mEvent, this ) ) {
       delete mEvent;
       mEvent = 0;
       return false;
--- branches/KDE/3.5/kdepim/korganizer/kojournaleditor.cpp #622164:622165
 @ -149,7 +149,7  @
 
     writeJournal( mJournal );
 
-    if ( !mChanger->addIncidence( mJournal ) ) {
+    if ( !mChanger->addIncidence( mJournal, this ) ) {
       KODialogManager::errorSaveIncidence( this, mJournal );
       delete mJournal;
       mJournal = 0;
--- branches/KDE/3.5/kdepim/korganizer/kotodoeditor.cpp #622164:622165
 @ -223,7 +223,7  @
 
     writeTodo( mTodo );
 
-    if ( !mChanger->addIncidence( mTodo ) ) {
+    if ( !mChanger->addIncidence( mTodo, this ) ) {
       delete mTodo;
       mTodo = 0;
       return false;
--- branches/KDE/3.5/kdepim/korganizer/kotodoview.cpp #622164:622165
 @ -236,7 +236,7  @
     } else {
 //      kdDebug(5850) << "Drop new Todo" << endl;
       todo->setRelatedTo(destinationEvent);
-      if ( !mChanger->addIncidence( todo ) ) {
+      if ( !mChanger->addIncidence( todo, this ) ) {
         KODialogManager::errorSaveIncidence( this, todo );
         delete todo;
         return;
 @ -980,7 +980,7  @
    if ( newTodo->doesRecur() )
      newTodo->recurrence()->unsetRecurs();
 
-   mChanger->addIncidence( newTodo );
+   mChanger->addIncidence( newTodo, this );
  }
 }
 
 @ -1105,7 +1105,7  @
     todo->setSummary( mQuickAdd->text() );
     todo->setOrganizer( Person( KOPrefs::instance()->fullName(),
                         KOPrefs::instance()->email() ) );
-    if ( !mChanger->addIncidence( todo ) ) {
+    if ( !mChanger->addIncidence( todo, this ) ) {
       KODialogManager::errorSaveIncidence( this, todo );
       delete todo;
       return;
--- branches/KDE/3.5/kdepim/libkcal/calendarresources.cpp #622164:622165
 @ -79,7 +79,7  @
   }
 
   KRES::Resource *r;
-  r = KRES::SelectDialog::getResource( list, mParent );
+  r = KRES::SelectDialog::getResource( list, parent() );
   return static_cast<ResourceCalendar *>( r );
 }
 
 @ -179,6 +179,16  @
   mDestinationPolicy = mAskPolicy;
 }
 
+QWidget *CalendarResources::dialogParentWidget()
+{
+  return mDestinationPolicy->parent();
+}
+void CalendarResources::setDialogParentWidget( QWidget *parent )
+{
+  mDestinationPolicy->setParent( parent );
+}
+
+
 void CalendarResources::close()
 {
   kdDebug(5800) << "CalendarResources::close" << endl;
--- branches/KDE/3.5/kdepim/libkcal/calendarresources.h #622164:622165
 @ -73,10 +73,13  @
     class DestinationPolicy
     {
       public:
-        DestinationPolicy( CalendarResourceManager *manager ) :
-          mManager( manager ) {}
+        DestinationPolicy( CalendarResourceManager *manager,
+                              QWidget *parent = 0  ) :
+          mManager( manager ), mParent( parent ) {}
 
         virtual ResourceCalendar *destination( Incidence *incidence ) = 0;
+        virtual QWidget *parent() { return mParent; }
+        virtual void setParent( QWidget *newparent ) { mParent = newparent; }
 
       protected:
         CalendarResourceManager *resourceManager()
 @ -84,6 +87,7  @
 
       private:
         CalendarResourceManager *mManager;
+        QWidget *mParent;
     };
 
     /**
 @ -92,8 +96,9  @
     class StandardDestinationPolicy : public DestinationPolicy
     {
       public:
-        StandardDestinationPolicy( CalendarResourceManager *manager ) :
-          DestinationPolicy( manager ) {}
+        StandardDestinationPolicy( CalendarResourceManager *manager,
+                              QWidget *parent = 0  ) :
+          DestinationPolicy( manager, parent ) {}
 
         ResourceCalendar *destination( Incidence *incidence );
 
 @ -110,13 +115,11  @
       public:
         AskDestinationPolicy( CalendarResourceManager *manager,
                               QWidget *parent = 0 ) :
-          DestinationPolicy( manager ), mParent( parent ) {}
+          DestinationPolicy( manager, parent ) {}
 
         ResourceCalendar *destination( Incidence *incidence );
 
       private:
-        QWidget *mParent;
-
         class Private;
         Private *d;
     };
 @ -250,6 +253,23  @
        Resource which is queried.
     */
     void setAskDestinationPolicy();
+    
+    /** 
+       Returns the current parent for new dialogs. This is a bad hack, but we need
+       to properly set the parent for the resource selection dialog. Otherwise
+       the dialog will not be modal to the editor dialog in korganizer and 
+       the user can still work in the editor dialog (and thus crash korganizer).
+       Afterwards we need to reset it (to avoid pointers to widgets that are 
+       already deleted) so we also need the accessor
+    */
+    QWidget *dialogParentWidget();
+    /** 
+       Set the widget parent for new dialogs. This is a bad hack, but we need
+       to properly set the parent for the resource selection dialog. Otherwise
+       the dialog will not be modal to the editor dialog in korganizer and 
+       the user can still work in the editor dialog (and thus crash korganizer).
+    */
+    void setDialogParentWidget( QWidget *parent );
 
     /**
        Request ticket for saving the Calendar.  If a ticket is returned the
--- branches/KDE/3.5/kdepim/libkdepim/kdateedit.cpp #622164:622165
 @ -271,6 +271,7  @
         step = 1;
       else if ( keyEvent->key() == Qt::Key_Down )
         step = -1;
+      // TODO: If it's not an input key, but something like Return, Enter, Tab, etc..., don't eat the keypress, but handle it through to the default eventfilter!
       if ( step && !mReadOnly ) {
         QDate date = parseDate();
         if ( date.isValid() ) {


More information about the Korganizer-devel mailing list