Hello community, here is the log from the commit of package fate for openSUSE:Factory checked in at 2017-08-01 09:25:26 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/fate (Old) and /work/SRC/openSUSE:Factory/.fate.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "fate" Tue Aug 1 09:25:26 2017 rev:9 rq:513159 version:1.6.0.2 Changes: -------- --- /work/SRC/openSUSE:Factory/fate/fate.changes 2017-06-28 10:37:28.001358357 +0200 +++ /work/SRC/openSUSE:Factory/.fate.new/fate.changes 2017-08-01 09:26:02.838048737 +0200 @@ -1,0 +2,23 @@ +Mon Jul 31 08:36:05 UTC 2017 - jplack@suse.com + +- bugfix release 1.6.0.2 + * fix bsc#1050997 in query by ids, thanks to reporter afaerber@ + and aschwab@ + * fix freeze/unfreeze in FeatureTableView + * do not copy xml representation in Feature::operator= + * eliminate public method FeatureMap::recordChange that nobody needs + * FeatureMapListView: derive directly from FeatureTableView + * fix reloading of single features, eliminate signal + FeatureMap::featureReloaded() + * let FeatureView handle its stuff alone in MainView + * handle signals from FeatureMap properly in FeatureView if they apply + * add a new public method FeatureMap::addNewFeature, making + addFeature/addFeatures protected + * hide progress bar after Feature import or cloning + * make Feature::operator= an internal operation for friend classes only + * do not bail out on new Features in FeatureDiffView::showFeatureChanges + * remove non-emitted signal FeatureDisplay::featureSelected(Feature*) + * remove FeatureMap* from FeatureView constructor + * fix bug in Feature::operator= + +------------------------------------------------------------------- Old: ---- fate-20170627-b434f6b5.tar.bz2 New: ---- fate-20170731-4baa429b.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ fate.spec ++++++ --- /var/tmp/diff_new_pack.gVMWFc/_old 2017-08-01 09:26:03.373973207 +0200 +++ /var/tmp/diff_new_pack.gVMWFc/_new 2017-08-01 09:26:03.377972644 +0200 @@ -17,8 +17,8 @@ %define baseversion 1.6 -%define patchlevel .0.1 -%define snapshot 20170627-b434f6b5 +%define patchlevel .0.2 +%define snapshot 20170731-4baa429b Name: fate Version: %{baseversion}%{patchlevel} Release: 0 ++++++ fate-20170627-b434f6b5.tar.bz2 -> fate-20170731-4baa429b.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fate-20170627-b434f6b5/src/fate/editor/featurediffview.cpp new/fate-20170731-4baa429b/src/fate/editor/featurediffview.cpp --- old/fate-20170627-b434f6b5/src/fate/editor/featurediffview.cpp 2017-06-27 16:44:59.458786761 +0200 +++ new/fate-20170731-4baa429b/src/fate/editor/featurediffview.cpp 2017-07-31 10:53:53.773448590 +0200 @@ -149,24 +149,29 @@ { if (!isVisible() || !mFeature) return; + Feature *oldRev; - FeatureMap *fmap = mFeature->featureMap(); - if (!fmap) - return; - - Feature *oldRev = fmap->origFeature( mFeature ); - - if ( !oldRev ) { - setPlainText( i18n("Caching has to be enabled to create diffs.\n\n" - "Please enable cached queries first.") ); - return; + if (mFeature->isNew()) { + oldRev = new Feature; + oldRev->createDomTree( false ); + } + else { + FeatureMap *fmap = mFeature->featureMap(); + if (!fmap) + return; + oldRev = fmap->origFeature( mFeature ); + + if (!oldRev) { + setPlainText( i18n("Caching has to be enabled to create diffs.\n\n" + "Please enable cached queries first.") ); + return; + } } if (mOldFile) { // still another diff process running qWarning() << "still another diff process running"; return; } - qWarning() << Q_FUNC_INFO << "Feature #" << mFeature->id(); // update XML representation mFeature->createDomTree( false ); @@ -249,7 +254,6 @@ { QString output; - qWarning() << Q_FUNC_INFO << proc << success; if (!success) output = i18n("diff process failed"); else if (!proc->getStandardOutput(output)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fate-20170627-b434f6b5/src/fate/editor/featuredisplay.h new/fate-20170731-4baa429b/src/fate/editor/featuredisplay.h --- old/fate-20170627-b434f6b5/src/fate/editor/featuredisplay.h 2017-06-27 16:44:59.458786761 +0200 +++ new/fate-20170731-4baa429b/src/fate/editor/featuredisplay.h 2017-07-31 10:53:53.773448590 +0200 @@ -56,7 +56,6 @@ virtual void showEvent(QShowEvent * event); signals: - void featureSelected( Feature * ); void commentRequest( int ); void commentEditRequest( int ); void commentToPublicRequest( int ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fate-20170627-b434f6b5/src/fate/editor/featureview.cpp new/fate-20170731-4baa429b/src/fate/editor/featureview.cpp --- old/fate-20170627-b434f6b5/src/fate/editor/featureview.cpp 2017-06-27 16:44:59.458786761 +0200 +++ new/fate-20170731-4baa429b/src/fate/editor/featureview.cpp 2017-07-31 10:53:53.777448609 +0200 @@ -56,8 +56,8 @@ { NULL, QString::null, 0, 0 } }; -FeatureView::FeatureView(FeatureMap *features, QWidget *parent) -: QTabWidget(parent), mFeatureMap(features), +FeatureView::FeatureView(QWidget *parent) +: QTabWidget(parent), mFeatureMap(0), mFeatureDisplay(0), mSimpleEditor(0), mEcoEditor(0), mCommentsView(0), mChangesView(0), mHistoryView(0), mRawXMLView(0), mMultiOpView(0), mCommentDialog(0), mReadOnly(false) @@ -128,7 +128,6 @@ void FeatureView::menuTriggered(QAction *action) { - qWarning() << Q_FUNC_INFO << action->text() << action->data() << action->objectName(); int number = action->data().toInt(); switch(number) { @@ -178,7 +177,9 @@ action->setEnabled(featureModified); action = mMenu->findChild<QAction *>("saveAll"); if (action) - action->setEnabled(mFeatureMap->modifiedFeatures().size() > featureModified); + action->setEnabled(mFeatureMap ? + mFeatureMap->modifiedFeatures().size() > featureModified + : false); action = mMenu->findChild<QAction *>("configure"); if (action) { FeatureViewBase *viewer = dynamic_cast<FeatureViewBase *>(currentWidget()); @@ -205,8 +206,6 @@ SLOT( slotFeatureSelected( const QString & ) )); connect( mFeatureDisplay, SIGNAL( showTreeRequest(const QString &) ), SIGNAL( showTreeRequest(const QString &) ) ); - connect( mFeatureDisplay, SIGNAL( featureSelected( Feature * ) ), - SIGNAL( featureSelected( Feature * ) ) ); } return mFeatureDisplay; } @@ -317,10 +316,15 @@ FeatureViewBase_setFeature(feature); + if ( mFeatureMap ) { + mFeatureMap->disconnect(this); + mFeatureMap = 0; + } + if (!mFeature) { mFeatureDisplay->clear(); if (mChangesView) - mChangesView->setFeature(0); + mChangesView->clear(); if (mSimpleEditor) mSimpleEditor->clear(); if (mEcoEditor) @@ -328,6 +332,12 @@ return; } + mFeatureMap = mFeature->featureMap(); + if ( mFeatureMap && mFeatureMap->view() == this) { + connect( mFeatureMap, SIGNAL( currentFeatureChanged( Feature * ) ), + SLOT( setFeature( Feature * ) ) ); + } + if (mFeature->eco()) { // show ECO tab QAction *action = mMenu->actions().at(1); // entry for ecoEditor @@ -433,6 +443,8 @@ void FeatureView::saveCurrentFeature() { + if (!mFeature || !mFeatureMap) + return; if (!mFeature->isModified()) return; if (!mFeatureMap->saveKeeper(mFeature)) { @@ -442,6 +454,8 @@ void FeatureView::saveAllFeatures() { + if (!mFeature || !mFeatureMap) + return; if (!mFeatureMap->isModified()) return; if (!mFeatureMap->saveModifiedFeatures()) { @@ -502,9 +516,6 @@ void FeatureView::slotTabChanged( QWidget *w ) { - if (w == mFeatureDisplay) { - mFeatureDisplay->setFeature( mFeature ); - } if (mMultiOpView && w != mMultiOpView) { // hide multiOp tab QAction *action = mMenu->actions().at(5); // keep in sync with featureViewTab[] @@ -552,8 +563,6 @@ { if ( mFeature != f ) { setFeature( f ); - // showFeature does already do a 'select´ and emits this signal - // emit featureSelected( f ); } if ( mFeatureDisplay->isVisible() ) { saveComments(); @@ -637,13 +646,16 @@ void FeatureView::slotFeatureSelected( const QString &id ) { + if (!mFeatureMap) + return; + Feature *f = mFeatureMap->feature( id ); // moved that code from FeatureDisplay !! // !! and _add_ the feature to the current feature set __and__ to // !! the querystring ... !! // currentQuery.unite( Query( id.toNum() ) ); ?? - if( !f || !mFeatureMap->features().contains( f ) ) { + if ( !f ) { int res = KMessageBox::questionYesNo( this, i18n( "The requested feature is not part of the current feature set. " "Fate can load it, but the feature set will then no longer match " @@ -656,15 +668,14 @@ } mFeatureMap->doRestock( id ); + if (f) + mFeatureMap->setCurrentFeature(f); } void FeatureView::saveComments() { mFeature->createDomTree( true ); mFeatureDisplay->setFeature( mFeature ); - /* the call to showFeature sets the feature unmodified - * again. But it is modified because of the new comment - */ } Feature* FeatureView::currentFeature() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fate-20170627-b434f6b5/src/fate/editor/featureview.h new/fate-20170731-4baa429b/src/fate/editor/featureview.h --- old/fate-20170627-b434f6b5/src/fate/editor/featureview.h 2017-06-27 16:44:59.458786761 +0200 +++ new/fate-20170731-4baa429b/src/fate/editor/featureview.h 2017-07-31 10:53:53.777448609 +0200 @@ -28,7 +28,6 @@ #include "featureviewbase.h" #include <QTabWidget> -#include <QWidget> class CommentDialog; class EcoEditor; @@ -42,6 +41,7 @@ class KActionCollection; class QComboBox; class QMenu; +class QWidget; class SimpleEditor; struct FateTabEntry { @@ -56,7 +56,7 @@ { Q_OBJECT public: - FeatureView( FeatureMap *, QWidget *parent ); + FeatureView( QWidget *parent ); virtual ~FeatureView(); void setupActions( KActionCollection * ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fate-20170627-b434f6b5/src/fate/editor/htmlview.cpp new/fate-20170731-4baa429b/src/fate/editor/htmlview.cpp --- old/fate-20170627-b434f6b5/src/fate/editor/htmlview.cpp 2017-06-27 16:44:59.458786761 +0200 +++ new/fate-20170731-4baa429b/src/fate/editor/htmlview.cpp 2017-07-31 10:53:53.777448609 +0200 @@ -92,7 +92,7 @@ void HtmlView::clearView() { begin(); - write( QString::null ); + write("<html><body></body></html>"); end(); setTitle( QString::null ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fate-20170627-b434f6b5/src/fate/mainview.cpp new/fate-20170731-4baa429b/src/fate/mainview.cpp --- old/fate-20170627-b434f6b5/src/fate/mainview.cpp 2017-06-27 16:44:59.462786781 +0200 +++ new/fate-20170731-4baa429b/src/fate/mainview.cpp 2017-07-31 10:53:53.777448609 +0200 @@ -2,8 +2,10 @@ This file is part of Fate. Copyright (c) 2005 SUSE LINUX Products GmbH + 2017 SUSE Linux GmbH - Author: Cornelius Schumacher <cschum@suse.de> + Author: Cornelius Schumacher <cschum@suse.de>, + Joachim Plack <jplack@suse.de> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,9 +26,6 @@ #include "prefs.h" #include "querylog.h" -#include <QBoxLayout> -#include <QHBoxLayout> -#include <QVBoxLayout> #include "feature.h" #include "featureview.h" #include "featurelistview.h" @@ -75,29 +74,25 @@ #include <kdialog.h> #include <kio/job.h> #include <kstandarddirs.h> -#include <kuser.h> #include <kaction.h> #include <kshortcut.h> -#include <ksavefile.h> #include <ksqueezedtextlabel.h> -#include <kdeversion.h> -#include <qlineedit.h> -#include <qlayout.h> -#include <qpushbutton.h> -#include <qtextedit.h> -#include <qlabel.h> -#include <qsplitter.h> -#include <qregexp.h> -#include <qcombobox.h> -#include <qtimer.h> -#include <qcursor.h> -#include <qapplication.h> -#include <qsignalmapper.h> +#include <QApplication> +#include <QBoxLayout> +#include <QComboBox> +#include <QCursor> #include <QDBusConnection> +#include <QHBoxLayout> +#include <QLabel> +#include <QLineEdit> +#include <QRegExp> +#include <QSignalMapper> +#include <QSplitter> #include <QTabWidget> - -#define BULK_FEATURE_UPDATES +#include <QTextStream> +#include <QTimer> +#include <QVBoxLayout> MainView::MainView( QWidget *parent, bool quietStartup ) : QWidget( parent ), mQuietStartup( quietStartup ), @@ -166,63 +161,32 @@ connect( mRelationTreeView, SIGNAL( newButtonClicked() ), SLOT( newRelationTree() ) ); connect( mRelationTreeView, SIGNAL( featureSelected(Feature *) ), - SLOT( showFeature(Feature *)) ); + &mFeatureMap, SLOT( setCurrentFeature(Feature *)) ); vbl->addWidget( mRelationTreeView ); mNavigatorTab->addTab( w, i18n("Relation &Trees") ); - mFeatureListView = new FeatureTableView( mNavigatorSplitter ); + mFeatureMapListView = new FeatureMapListView( mNavigatorSplitter, &mFeatureMap); - mFeatureView = new FeatureView( &mFeatureMap, rightSplitter ); + // TODO: remove parameter mFeatureMap, this can be read from the feature in setFeature + mFeatureView = new FeatureView( rightSplitter ); mFeatureMap.setView( mFeatureView ); connect( &mFeatureMap, SIGNAL( statusMessage( const QString & ) ), SIGNAL( statusMessage( const QString & ) ) ); connect( &mFeatureMap, SIGNAL( queryDone( bool ) ), SLOT( slotQueryDone() ) ); - connect( &mFeatureMap, SIGNAL( queryDone( bool ) ), - mFeatureListView, SLOT( unfreeze() ) ); - connect( &mFeatureMap, SIGNAL( dataAboutToBeReset() ), - SLOT( clearFeatureViews() ) ); - connect( &mFeatureMap, SIGNAL( dataAboutToBeReset() ), - mFeatureListView, SLOT( freeze() ) ); - connect( mFeatureListView, SIGNAL( requestFeatureView( Feature * ) ), - SLOT( showNewFeatureView( Feature * ) ) ); - - // This signal/slot connection causes features to be added to the - // table/list view one by one. Which is fine for a small number of - // features, but tends to get slow with larger numbers. This is - // mostly due to table sorting, it appears. -#ifndef BULK_FEATURE_UPDATES - connect( &mFeatureMap, SIGNAL( featureAdded( Feature * ) ), - mFeatureListView, SLOT( insertFeature( Feature * ) ) ); -#endif - - connect( &mFeatureMap, SIGNAL( featureChanged( Feature * ) ), - mFeatureListView, SLOT( updateFeature( Feature * ) ) ); - connect( &mFeatureMap, SIGNAL( featureReloaded( Feature * ) ), - mFeatureListView, SLOT( updateFeature( Feature * ) ) ); connect( &mFeatureMap, SIGNAL( dataChanged() ), SLOT( slotFeatureDataChanged() ) ); - connect( &mFeatureMap, SIGNAL( featureReloaded( Feature * ) ), + + // Thinks we do not need that in the end ... + connect( &mFeatureMap, SIGNAL( featureChanged( Feature * ) ), SLOT( slotFeatureReloaded( Feature * ) ) ); connect( &mFeatureMap, SIGNAL( connectionEstablished( bool ) ), SIGNAL( connectionEstablished( bool ) ) ); - // this gets connected only for the first FeatureView and is the only valid - // way to change the displayed feature for it - connect( &mFeatureMap, SIGNAL( currentFeatureChanged( Feature * ) ), - mFeatureView, SLOT( setFeature( Feature * ) ) ); - connect( mFeatureListView, SIGNAL( featureSelected( Feature * ) ), - SLOT( showFeature( Feature * ) ) ); - /* - connect( mFeatureView, SIGNAL( featureSelected( Feature * ) ), - mFeatureListView, SLOT( selectFeature( Feature * ) ) ); - */ - // TODO: looks like this can be removed both, the second should signal - // FeatureMap instead - connect( mFeatureView, SIGNAL( featureSelected( Feature * ) ), - &mFeatureMap, SLOT( setCurrentFeature( Feature * ) ) ); - connect( mFeatureView, SIGNAL( featureSelected( Feature * ) ), - SLOT( showFeature( Feature * ) ) ); + // TODO: may be move this completely to FeatureMapListView + connect( mFeatureMapListView, SIGNAL( requestFeatureView( Feature * ) ), + SLOT( showNewFeatureView( Feature * ) ) ); + connect( mFeatureView, SIGNAL(showTreeRequest( const QString & ) ), SLOT( showTree( const QString & ) ) ); @@ -274,6 +238,10 @@ Prefs::self()->writeConfig(); delete mClientInfo; + delete mFeatureView; + delete mFeatureMapListView; + delete mStatisticsView; + delete mRelationTreeView; } void MainView::showNewFeatureView(Feature *feature) @@ -282,7 +250,7 @@ if (!mFeatureMap.features().contains(feature)) return; - FeatureView *view = new FeatureView(&mFeatureMap, NULL); + FeatureView *view = new FeatureView(NULL); view->setFeature(feature); KActionCollection c(view); view->setupActions( &c ); @@ -291,10 +259,25 @@ connect( &mFeatureMap, SIGNAL(dataAboutToBeReset()), view, SLOT(close())); - view->resize(800, 600); // better load last geometry + disconnect( feature, SIGNAL(destroyed()), + view, 0); + connect( feature, SIGNAL(destroyed()), + view, SLOT(close())); + connect( view, SIGNAL(destroyed()), + SLOT(aboutToDestroyFeatureView())); + // TODO: load and store a default size + view->resize(800, 600); view->show(); } +void MainView::aboutToDestroyFeatureView() +{ + // FeatureView *view == sender(); + + emit statusMessage("FeatureView about to be destroyed"); +} + + void MainView::editRelationTree() { if( Prefs::self()->offlineModeEnabled() ) { @@ -334,7 +317,7 @@ dlg.setProductMap( ProductMap::self() ); dlg.showTree( mRelationTreeView->currentTree() ); connect( &dlg, SIGNAL( featureSelected(Feature *) ), - SLOT( showFeature(Feature *)) ); + &mFeatureMap, SLOT( setCurrentFeature(Feature *)) ); dlg.exec(); } @@ -351,7 +334,7 @@ dlg.setProductMap( ProductMap::self() ); dlg.showTree( tree ); connect( &dlg, SIGNAL( featureSelected(Feature *) ), - SLOT( showFeature(Feature *)) ); + &mFeatureMap, SLOT( setCurrentFeature(Feature *)) ); dlg.exec(); } @@ -659,7 +642,7 @@ connect( mLoadMissingFeaturesAction, SIGNAL( triggered() ), mRelationTreeView, SLOT( stockTree() ) ); c->addAction( "stock_tree", mLoadMissingFeaturesAction ); - + /* KAction* kaction = new KAction( this ); kaction->setText( i18n("Select next feature") ); kaction->setShortcut( Qt::CTRL+Qt::Key_Down ); @@ -671,9 +654,10 @@ kaction->setShortcut( Qt::CTRL+Qt::Key_Up ); connect( kaction, SIGNAL( triggered() ), SLOT(selectPreviousFeature())); c->addAction( "select_previous_feature", action ); - + */ updateStoredQueriesView(); mFeatureView->setupActions( c ); + mFeatureMapListView->setupActions( c ); } void MainView::submitQuery( const Query &query ) @@ -1048,9 +1032,8 @@ Feature *f = dlg->feature(); f->setModified(true); - mFeatureMap.addFeature(f); + mFeatureMap.addNewFeature(f); mFeatureMap.setCurrentFeature(f); - mFeatureView->setFeature(f); mFeatureView->focusEditor(); } } @@ -1067,12 +1050,14 @@ FeatureParser parser; connect( &parser, SIGNAL(featureParsed( Feature * )), - &mFeatureMap, SLOT(addFeature( Feature * )) ); + &mFeatureMap, SLOT(addNewFeature( Feature * )) ); clonedFeature = new Feature; clonedFeature->setModified(true); KResult result = parser.parseFeature(clonedFeature, xml); + emit queryDone(); // hide progress bar again + if (!result) { KMessageBox::sorry(this, result.fullMessage()); // FIXME: do we need to delete clonedFeature? @@ -1099,7 +1084,7 @@ if (!mFeatureMap.checkModified(true)) return; - f = mFeatureView->currentFeature(); + f = mFeatureMap.currentFeature(); if (f == 0) { KMessageBox::sorry(this, i18n("No feature selected.")); return; @@ -1107,7 +1092,7 @@ f = doClone(f, true); if (f != 0) - showFeature(f); + mFeatureMap.setCurrentFeature(f); } void MainView::cloneFeatureWithoutComments() @@ -1117,7 +1102,7 @@ if (!mFeatureMap.checkModified(true)) return; - f = mFeatureView->currentFeature(); + f = mFeatureMap.currentFeature(); if (f == 0) { KMessageBox::sorry(this, i18n("No feature selected.")); return; @@ -1125,7 +1110,7 @@ f = doClone(f, false); if (f != 0) - showFeature(f); + mFeatureMap.setCurrentFeature(f); } void MainView::importFeature() @@ -1145,9 +1130,11 @@ FeatureParser parser; connect( &parser, SIGNAL(featureParsed( Feature * )), - mFeatureView, SLOT(addFeature( Feature * )) ); + &mFeatureMap, SLOT(addNewFeature( Feature * )) ); KResult result = parser.parse( xml ); + emit queryDone(); // hide progress bar again + if ( !result ) KMessageBox::sorry( this, result.fullMessage() ); } @@ -1156,27 +1143,16 @@ ImportBugzillaDialog dlg( ProductMap::self(), this ); connect( &dlg, SIGNAL( featureParsed( Feature * ) ), - &mFeatureMap, SLOT( addFeature( Feature * ) ) ); + &mFeatureMap, SLOT( addNewFeature( Feature * ) ) ); dlg.exec(); } -void MainView::updateFeatureList( Feature *f ) -{ - kDebug() << k_funcinfo << f->id(); - - mFeatureListView->insertFeature( f ); - mFeatureListView->updateView(); -// TODO: Add to tree view. -// mTreeView->addFeature( f ); - // TODO: Update info in list view item -} - void MainView::reloadFeature( Feature *f ) { Feature *feature = f; - if ( !feature ) feature = mFeatureView->currentFeature(); + if ( !feature ) feature = mFeatureMap.currentFeature(); if ( !feature ) { KMessageBox::sorry( this, i18n("No feature selected.") ); @@ -1192,12 +1168,10 @@ void MainView::slotFeatureReloaded( Feature * f ) { - Feature *currentFeature = mFeatureView->currentFeature(); + Feature *currentFeature = mFeatureMap.currentFeature(); if ( !currentFeature || currentFeature->id() == f->id() ) { - showFeature( f ); + mFeatureView->setFeature( f ); } - - updateFeatureList( f ); } void MainView::doDelayedQuery() @@ -1248,17 +1222,6 @@ void MainView::slotQueryDone() { -#ifdef BULK_FEATURE_UPDATES - /* bsc#899494 - * The problem here is that mFeatureMap emits dataChanged() from - * FeatureMap::slotQueryDone() and FeatureTableView::slotProductChosen - * correctly processess the signal BUT at that time there are no features in - * the table as FeatureTableView::insertFeatures() gets called only after the - * signal is processed. This needs redesign. - */ - mFeatureListView->insertFeatures(mFeatureMap.features()); -#endif - emit queryDone(); QApplication::restoreOverrideCursor(); } @@ -1651,7 +1614,7 @@ void MainView::showHistory() { - Feature *f = mFeatureView->currentFeature(); + Feature *f = mFeatureMap.currentFeature(); if ( f ) { HistoryDialog *dlg = new HistoryDialog( f, this ); dlg->show(); @@ -1730,27 +1693,6 @@ mLoadMissingFeaturesAction->setEnabled( enabled ); } -void MainView::showFeature( Feature *feature ) -{ - if( !feature ) { - return; - } - - if( feature != mFeatureView->currentFeature() && - !mFeatureMap.checkModified( true ) ) { - QTimer::singleShot( 0, this, SLOT(reselectFeature()) ); - return; - } - - mFeatureView->setFeature( feature ); -} - -void MainView::reselectFeature() -{ - mFeatureListView->clearSelection(); - mFeatureListView->selectFeature( mFeatureView->currentFeature() ); -} - bool MainView::goOnline() { if( !mFeatureMap.checkSynch( true ) ) @@ -1817,7 +1759,7 @@ FeatureTableDialog dlg( ProductMap::self(), this ); connect( &dlg, SIGNAL( featureSelected( Feature *) ), - SLOT( showFeature( Feature * ) ) ); + &mFeatureMap, SLOT( setCurrentFeature( Feature * ) ) ); dlg.setFeatures( mFeatureMap.features() ); dlg.exec(); @@ -1852,19 +1794,9 @@ dlg.exec(); } -void MainView::clearFeatureViews() -{ - mFeatureListView->clear(); - mFeatureView->clear(); -} - void MainView::slotFeatureDataChanged() { - mFeatureListView->updateView(); - mFeatureListView->updateQueryTitle( mFeatureMap.currentQuery().title() ); - mFeatureListView->updateProductList( mFeatureMap.productList() ); - StartupSequence::self()->setPrecondition( StartupSequence::StartupQueryDone, true ); @@ -1883,14 +1815,14 @@ if ( f ) kDebug() << k_funcinfo << "Showing first feature: " << f->id(); else kDebug() << k_funcinfo << "Unable to find first feature."; } - mFeatureListView->selectFeature( f ); - showFeature( f ); + mFeatureMap.setCurrentFeature(f); + mFeatureView->setFeature(f); } QString MainView::currentURL() const { - if( mFeatureView->currentFeature() ) { - return QString( "fate://%1" ).arg( mFeatureView->currentFeature()->id() ); + if( mFeatureMap.currentFeature() ) { + return QString( "fate://%1" ).arg( mFeatureMap.currentFeature()->id() ); } return QString::null; } @@ -1898,7 +1830,7 @@ QString MainView::currentTitle() const { - Feature *f = mFeatureView->currentFeature(); + Feature *f = mFeatureMap.currentFeature(); if( f ) return QString( "#%1: %2" ).arg( f->id(), f->title() ); return QString::null; @@ -1923,14 +1855,4 @@ dlg.exec(); } -void MainView::selectNextFeature() -{ - mFeatureListView->selectNext(); -} - -void MainView::selectPreviousFeature() -{ - mFeatureListView->selectPrevious(); -} - #include "mainview.moc" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fate-20170627-b434f6b5/src/fate/mainview.h new/fate-20170731-4baa429b/src/fate/mainview.h --- old/fate-20170627-b434f6b5/src/fate/mainview.h 2017-06-27 16:44:59.462786781 +0200 +++ new/fate-20170731-4baa429b/src/fate/mainview.h 2017-07-31 10:53:53.777448609 +0200 @@ -2,8 +2,10 @@ This file is part of Fate. Copyright (c) 2005 SUSE LINUX Products GmbH + 2017 SUSE Linux GmbH - Author: Cornelius Schumacher <cschum@suse.de> + Author: Cornelius Schumacher <cschum@suse.de>, + Joachim Plack <jplack@suse.de> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,34 +32,26 @@ #include "dcopfateiface.h" #include "startupsequence.h" -#include <qwidget.h> -#include <qdom.h> - -#include <sys/time.h> - -class QLineEdit; -class FeatureTableView; -class QueryLogDialog; -class QComboBox; -class QLabel; -class QSplitter; -class KActionCollection; -class QTabWidget; -class QPushButton; -class QSignalMapper; +#include <QWidget> +class ClientInfo; +class ExportJob; class Feature; +class FeatureMapListView; class FeatureView; class KAction; +class KActionCollection; class KActionMenu; -class XQueryDialog; -class ExportJob; -class RelationTreeView; +class QSignalMapper; +class QSplitter; +class QTabWidget; +class QueryLogDialog; class RelationList; class RelationQueryEngine; +class RelationTreeView; class StatisticsView; -class ClientInfo; class TextTemplate; +class XQueryDialog; class MainView : public QWidget // FIXME: DBusObject { @@ -101,15 +95,12 @@ void exportFeatureXml(); void showHistory(); void syncDatabase(); - void showFeature( Feature * ); void cancelQuery(); void printFeature() const; void slotProcessHelp(); void submitQuery( const Query & ); void submitLastQuery(); void sendMail(); - void selectNextFeature(); - void selectPreviousFeature(); signals: void statusMessage( const QString & ); @@ -166,20 +157,15 @@ void showProducts(); void slotPreconditionChanged( StartupSequence::Precondition p, bool on ); void slotFeatureDataChanged(); - void clearFeatureViews(); void slotQueryDone(); void slotFeatureReloaded( Feature * ); void keeperChanged( const QString & ); void clientLocked( bool ); - - // This is a hack to work around some signal/slot interaction weirdness - // TODO: Do this properly eventually - void reselectFeature(); - void editRelationTree(); void newRelationTree(); void showTree( const QString & ); void showNewFeatureView(Feature *); + void aboutToDestroyFeatureView(); private: KAction *mNewAction; @@ -211,7 +197,7 @@ QSplitter *mNavigatorSplitter; QTabWidget *mNavigatorTab; - FeatureTableView *mFeatureListView; + FeatureMapListView *mFeatureMapListView; FeatureView *mFeatureView; RelationTreeView *mRelationTreeView; StatisticsView *mStatisticsView; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fate-20170627-b434f6b5/src/libfate/feature.cpp new/fate-20170731-4baa429b/src/libfate/feature.cpp --- old/fate-20170627-b434f6b5/src/libfate/feature.cpp 2017-06-27 16:44:59.466786801 +0200 +++ new/fate-20170731-4baa429b/src/libfate/feature.cpp 2017-07-31 10:53:53.785448648 +0200 @@ -869,7 +869,7 @@ Feature& Feature::operator=( const Feature& f ) { - mDomElement = f.mDomElement; + mDomElement.clear(); mId = f.mId; mKeeperXmlns = f.mKeeperXmlns; mTitle = f.mTitle; @@ -900,7 +900,7 @@ mReleaseNotesSolution = f.mReleaseNotesSolution; mDoc = f.mDoc; mModified = f.mModified; - mFeatureMap = mFeatureMap; + mFeatureMap = f.mFeatureMap; if (mECO) delete mECO; @@ -909,6 +909,6 @@ else mECO = 0; - emit featureChanged(); + // emit featureChanged(); this is an internal operation for friend classes only return *this; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fate-20170627-b434f6b5/src/libfate/feature.h new/fate-20170731-4baa429b/src/libfate/feature.h --- old/fate-20170627-b434f6b5/src/libfate/feature.h 2017-06-27 16:44:59.466786801 +0200 +++ new/fate-20170731-4baa429b/src/libfate/feature.h 2017-07-31 10:53:53.785448648 +0200 @@ -39,6 +39,7 @@ class Feature : public QObject, public XCLObject { Q_OBJECT + protected: // QObject does not have a default operator= Feature& operator=( const Feature& f ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fate-20170627-b434f6b5/src/libfate/featuremap.cpp new/fate-20170731-4baa429b/src/libfate/featuremap.cpp --- old/fate-20170627-b434f6b5/src/libfate/featuremap.cpp 2017-06-27 16:44:59.466786801 +0200 +++ new/fate-20170731-4baa429b/src/libfate/featuremap.cpp 2017-07-31 10:53:53.785448648 +0200 @@ -158,6 +158,11 @@ mSaveEngine->setView( view ); } +QWidget *FeatureMap::view() const +{ + return mView; +} + const QStringList FeatureMap::productList() { QSet<QString> prodSet; // Use QSet for faster insertion of unique strings @@ -248,6 +253,13 @@ emit featureChanged( f ); } +void FeatureMap::addNewFeature(Feature *f) +{ + f->mId.clear(); + f->mModified = true; + addFeature(f); +} + void FeatureMap::addFeature(Feature *f) { if (f == 0) @@ -287,7 +299,12 @@ return; if( mCurrentFeature == f ) { - setCurrentFeature( 0 ); + // move to "next" feature in the list in the order of filling + // the FeatureMap, else take the previous or none + int ix = mFeatures.indexOf(f)+1; + if (ix >= mFeatures.size()) + ix = mFeatures.size()-2; + setCurrentFeature( mFeatures.value(ix, NULL) ); } mRevisionMap.remove( f->id() ); @@ -699,17 +716,14 @@ void FeatureMap::finishReload( Feature *f ) { + QString msg = i18n("Reloaded feature #%1").arg( f->id() ); mQueryTiming.stop(); - - QString s; - if ( Prefs::self()->showQueryTime() ) { - s += i18n(" (%1 s)").arg( mQueryTiming.getSecondsAsString() ); - } - - QString msg = i18n("Reloaded feature #%1%2").arg( f->id() ).arg( s ); + if ( Prefs::self()->showQueryTime() ) + msg += i18n(" (%1 s)").arg( mQueryTiming.getSecondsAsString() ); emit statusMessage( msg ); - emit featureReloaded( f ); - + f->setFeatureMap( this ); + f->setModified(false); // emit a Feature::featureChanged() and thus + // a FeatureMap::featureChanged(f) if( mCache ) { mCache->removeModifiedItem( f->id() ); } @@ -737,13 +751,6 @@ return mCurrentQuery; } -void FeatureMap::recordChange( Feature *f ) -{ - if ( mCache ) { - mCache->saveModifiedItem( f->id(), f ); - } -} - void FeatureMap::slotSaveDone( const QString &id ) { Feature *f = feature( id ); @@ -851,7 +858,7 @@ if( f->isNew() ) { mCache->saveNewItem( f ); } else { - recordChange( f ); + mCache->saveModifiedItem( f->id(), f ); } SaveResult r; r.feature = f; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fate-20170627-b434f6b5/src/libfate/featuremap.h new/fate-20170731-4baa429b/src/libfate/featuremap.h --- old/fate-20170627-b434f6b5/src/libfate/featuremap.h 2017-06-27 16:44:59.466786801 +0200 +++ new/fate-20170731-4baa429b/src/libfate/featuremap.h 2017-07-31 10:53:53.785448648 +0200 @@ -51,6 +51,7 @@ Feature *feature( const QString &id ) const; Feature *currentFeature() const; + QWidget *view() const; const Feature::List &features() const; Feature::List modifiedFeatures() const; bool hasNoModifiedFeatures() const; @@ -68,9 +69,7 @@ bool doSync( const QString &source, const QString &target ); Query currentQuery() const; - void recordChange( Feature * ); void saveOfflineProfile( const QString & ); - bool checkModified( bool askForSaving ); bool checkSynch( bool dataAboutToChange ); bool hasCachedModifiedFeatures() const; @@ -82,9 +81,7 @@ public slots: void cancelQuery(); - - void addFeature( Feature * ); - void addFeatures(QList<Feature *>); + void addNewFeature( Feature * ); void removeFeature( Feature * ); void signalFeatureModification( Feature *f = 0 ); @@ -111,8 +108,8 @@ // a new feature has been added to the feature map void featureAdded( Feature * ); + // a feature in the map has been changed void featureChanged( Feature * ); - void featureReloaded( Feature * ); // passthrough signal from QueryEngine void connectionEstablished( bool ); @@ -131,6 +128,7 @@ void currentFeatureChanged( Feature * ); protected: + void addFeatures(QList<Feature *>); void finishSave( Feature * ); void finishReload( Feature * ); @@ -141,6 +139,7 @@ void initCache(); protected slots: + void addFeature( Feature * ); void slotQueryRawResult( const QString &xml ); void slotQueryDone( bool ); void slotQueryIdResult( const QString &id, const QString &revision ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fate-20170627-b434f6b5/src/libfate/query.cpp new/fate-20170731-4baa429b/src/libfate/query.cpp --- old/fate-20170627-b434f6b5/src/libfate/query.cpp 2017-06-27 16:44:59.470786820 +0200 +++ new/fate-20170731-4baa429b/src/libfate/query.cpp 2017-07-31 10:53:53.785448648 +0200 @@ -31,7 +31,7 @@ Query::Query( int id ) { mTitle = QString("Feature #%1").arg(id); - mXquery = QString( "/feature[@k:id=%1]" ).arg( id ); + mXquery = QString( "/feature[@k:id='%1']" ).arg(id); } Query::Query( QList<int> &ids ) { @@ -40,7 +40,7 @@ idstrs << QString::number(id); mTitle = QString("Features #") + idstrs.join(",#"); - mXquery = QString("/feature[@k:id=%1]").arg(idstrs.join(" or @k:id=")); + mXquery = QString("/feature[@k:id='%1']").arg(idstrs.join("' or @k:id='")); } QString Query::guessTitle() const diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fate-20170627-b434f6b5/src/libfate/ui/featurelistview.cpp new/fate-20170731-4baa429b/src/libfate/ui/featurelistview.cpp --- old/fate-20170627-b434f6b5/src/libfate/ui/featurelistview.cpp 2017-06-27 16:44:59.470786820 +0200 +++ new/fate-20170731-4baa429b/src/libfate/ui/featurelistview.cpp 2017-07-31 10:53:53.789448668 +0200 @@ -29,6 +29,8 @@ #include <klocale.h> #include <kdialog.h> +#include <kaction.h> +#include <kactioncollection.h> #include <kapplication.h> #include <kiconloader.h> #include <ksqueezedtextlabel.h> @@ -196,9 +198,18 @@ if ( item==0 ) return; + Feature *feature = item->feature(); action = menu.addAction(i18n("Open feature in an additional window"), this, SLOT( createFeatureView() ), 0); - action->setData(qVariantFromValue((void *)(item->feature()))); + action->setData(qVariantFromValue((void *)(feature))); + + if (!feature->isModified()) { + action = menu.addAction(i18n("Remove feature from this list"), this, + SLOT( removeFeatureFromList() ), 0); + action->setData(qVariantFromValue((void *)(feature))); + + } + QPoint correction ( -mTableView->frameWidth(), mTableView->horizontalHeader()->height()-mTableView->frameWidth()); @@ -206,11 +217,15 @@ } void FeatureTableView::createFeatureView() { - QAction *action = dynamic_cast<QAction *>(sender()); emit requestFeatureView((Feature *)action->data().value<void *>()); } +void FeatureTableView::removeFeatureFromList() { + QAction *action = dynamic_cast<QAction *>(sender()); + emit requestRemoveFeature((Feature *)action->data().value<void *>()); +} + void FeatureTableView::updateProductList( const QStringList &prodList) { QString selected = mProductCombo->currentText(); @@ -449,15 +464,16 @@ mTableView->setSortingEnabled(true); mFilterHeader->updateView(); - - // workaround for bsc#899494, see also comment in MainView::slotQueryDone() - emit slotProductChosen(mProductCombo->currentText()); } void FeatureTableView::selectFeature( Feature *feature ) { - if (feature) - selectItem(findItemCreate(feature)); + if (!feature) + return; + NewFeatureItem *item = findItemCreate(feature); + if (!item || item->isSelected()) + return; + selectItem(item); } void FeatureTableView::selectItem( NewFeatureItem *item ) @@ -472,11 +488,6 @@ } } -void FeatureTableView::clearSelection() -{ - mTableView->clearSelection(); -} - void FeatureTableView::updateQueryTitle( const QString &title ) { mQueryTitle->setText(title.simplified()); // limit to a single line @@ -691,11 +702,13 @@ mFreezeWidget->setPixmap( QPixmap::grabWidget( mTableView ) ); mTableView->hide(); mFreezeWidget->show(); + mTableView->setSortingEnabled(false); } void FeatureTableView::unfreeze() { mFreezeWidget->hide(); + mTableView->setSortingEnabled(true); mTableView->show(); } @@ -778,4 +791,82 @@ mChecked = on; } +FeatureMapListView::FeatureMapListView(QWidget *parent, FeatureMap *featureMap) + : FeatureTableView(parent), mFeatureMap(featureMap) +{ + /* + * interesting signals from FeatureMap + * + // an asynchronous keeper query has been finished + void queryDone( bool ); + + void featureAdded( Feature * ); + void featureChanged( Feature * ); + + // selected feature changed + void currentFeatureChanged( Feature * ); + */ + + connect( mFeatureMap, SIGNAL( queryDone( bool ) ), + SLOT( queryDone() ) ); + connect( mFeatureMap, SIGNAL( featureAdded( Feature * ) ), + SLOT( insertFeature( Feature * ) ) ); + connect( mFeatureMap, SIGNAL( featureChanged( Feature * ) ), + SLOT( updateFeature( Feature * ) ) ); + // feature removed or map cleared and sometimes on reload and save + connect( mFeatureMap, SIGNAL( featuresModified() ), + SLOT( reload() ) ); + connect( mFeatureMap, SIGNAL( dataChanged() ), + SLOT( reload() ) ); + connect( mFeatureMap, SIGNAL( currentFeatureChanged( Feature * ) ), + SLOT( selectFeature( Feature * ) ) ); + + // handle signals from FeatureTableView + connect( this, SIGNAL( featureSelected( Feature * ) ), + mFeatureMap, SLOT( setCurrentFeature( Feature * ) ) ); + connect( this, SIGNAL( requestFeatureView( Feature * ) ), + SIGNAL( requestFeatureView( Feature * ) ) ); + connect( this, SIGNAL( requestRemoveFeature( Feature * ) ), + mFeatureMap, SLOT( removeFeature( Feature * ) ) ); +} + +FeatureMapListView::~FeatureMapListView() +{ + ; +} + +void FeatureMapListView::updateFeature(Feature *f) { + updateProductList(mFeatureMap->productList()); + FeatureTableView::updateFeature(f); +} + +void FeatureMapListView::queryDone() { + updateQueryTitle(mFeatureMap->currentQuery().title()); + updateProductList(mFeatureMap->productList() ); + selectFeature(mFeatureMap->currentFeature()); + unfreeze(); +} + +void FeatureMapListView::reload() +{ + freeze(); + clear(); + foreach (Feature *f, mFeatureMap->features()) + insertFeature(f); + queryDone(); +} + +void FeatureMapListView::setupActions( KActionCollection *c ) +{ + KAction* a = new KAction( this ); + a->setText( i18n("Remove Feature From List" ) ); + a->setShortcut( Qt::Key_Delete ); + connect(a, SIGNAL(triggered()), this, SLOT( removeCurrentFeature() ) ); + c->addAction( "remove_feature_from_list", a ); +} + +void FeatureMapListView::removeCurrentFeature() +{ + mFeatureMap->removeFeature(mFeatureMap->currentFeature()); +} #include "featurelistview.moc" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fate-20170627-b434f6b5/src/libfate/ui/featurelistview.h new/fate-20170731-4baa429b/src/libfate/ui/featurelistview.h --- old/fate-20170627-b434f6b5/src/libfate/ui/featurelistview.h 2017-06-27 16:44:59.470786820 +0200 +++ new/fate-20170731-4baa429b/src/libfate/ui/featurelistview.h 2017-07-31 10:53:53.789448668 +0200 @@ -23,6 +23,7 @@ #define FEATURELISTVIEW_H #include "feature.h" +#include "featuremap.h" #include <qwidget.h> #include <qmap.h> @@ -32,6 +33,7 @@ class TableFilterHeader; class TableViewToolTip; class NewFeatureItem; +class KActionCollection; class KSqueezedTextLabel; // XXX: Move this to featureitem.h later @@ -172,7 +174,6 @@ void insertFeature(Feature *); void insertFeatures(const Feature::List &); void selectFeature( Feature * ); - void clearSelection(); void updateFeature( Feature * ); void freeze(); void unfreeze(); @@ -180,6 +181,7 @@ signals: void featureSelected( Feature * ); void requestFeatureView(Feature *); + void requestRemoveFeature(Feature *); protected: void addColumnInternal(NewFeatureItem::Property, const QString &, int resizeMode); @@ -205,6 +207,7 @@ void slotProductChosen(const QString &); void showContextMenu(const QPoint & pos); void createFeatureView(); + void removeFeatureFromList(); protected: // FIXME: turn this into a QList<struct { type, label }> @@ -226,4 +229,25 @@ QComboBox *mProductCombo; }; +class FeatureMapListView : public FeatureTableView +{ + Q_OBJECT + public: + FeatureMapListView(QWidget *parent, FeatureMap *); + ~FeatureMapListView(); + void setupActions(KActionCollection*); + + signals: + void requestFeatureView(Feature *); + + protected slots: + void updateFeature(Feature *f); + void queryDone(); + void reload(); + void removeCurrentFeature(); + + protected: + FeatureMap *mFeatureMap; +}; + #endif
participants (1)
-
root@hilbert.suse.de