00001 #ifndef WIN32
00002 #ifndef __APPLE__
00003 #include <QtCore/QtDebug>
00004 #include <QtCore/QObject>
00005 #include <QtCore/QSettings>
00006 #include <QtCore/QCoreApplication>
00007 #include <QtCore/QPoint>
00008 #include <QtCore/QSize>
00009 #include <QtGui/QDockWidget>
00010 #include <QtGui/QHBoxLayout>
00011 #include <QtGui/QVBoxLayout>
00012 #include <QtGui/QTreeView>
00013 #include <QtGui/QCloseEvent>
00014 #include <QtGui/QMessageBox>
00015
00016 #include "ACE/MainWindow.h"
00017 #include "ACE/foldertreemodel.h"
00018 #include "ACE/foldertablemodel.h"
00019 #include "ACE/foldertableview.h"
00020 #include "ACE/foldertabledockwidget.h"
00021 #include "ACE/ConnectionDialog.h"
00022 #include "ACE/FilterBuilderDockWidget.h"
00023 #include "ACE/FolderOpenDialog.h"
00024 #include "ACE/ACE_Errors.h"
00025
00026
00027 MainWindow::MainWindow( QWidget *parent ):
00028 QMainWindow( parent ),
00029 connectionCounter( 0 )
00030 {
00031 setupUi( this );
00032 initialise_ACE_Settings();
00033 loadGUISettings();
00034 defaultConnectionTab = tabWidget_Connections->widget( 0 );
00035 connectionDialog = new ConnectionDialog( this );
00036 folderOpenDialog = new FolderOpenDialog( this );
00037 filterBuilderDockWidget = new FilterBuilderDockWidget( this );
00038 addDockWidget( Qt::TopDockWidgetArea, filterBuilderDockWidget );
00039 filterBuilderDockWidget->hide();
00040 setConnections();
00041 }
00042
00043 MainWindow::~MainWindow()
00044 {
00045 QSettings settings;
00046 qDeleteAll( folderTableModels );
00047 qDeleteAll( folderTreeViews );
00048 delete connectionDialog;
00049 delete folderOpenDialog;
00050 delete filterBuilderDockWidget;
00051 saveGUISettings();
00052 }
00053
00054 void MainWindow::setConnections()
00055 {
00056 QObject::connect( action_ConnectionOpen, SIGNAL( triggered() ), this, SLOT( slotConnectionOpen() ) );
00057 QObject::connect( action_FolderCommit, SIGNAL( triggered() ), this, SLOT( slotFolderCommit() ) );
00058 QObject::connect( connectionDialog, SIGNAL( buildFolderTree( cool::IDatabasePtr, const QString ) ), this, SLOT( slotCreateFolderTree( cool::IDatabasePtr, const QString ) ) );
00059 QObject::connect( action_FolderFilter, SIGNAL( toggled( bool ) ), this, SLOT( slotFolderFilter( bool ) ) );
00060 QObject::connect( action_FolderCommitAll, SIGNAL( triggered() ), this, SLOT( slotFolderCommitAll() ) );
00061 QObject::connect( action_ConnectionDisconnect, SIGNAL( triggered() ), this, SLOT( slotConnectionDisconnect() ) );
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 }
00072
00073 void MainWindow::initialise_ACE_Settings()
00074 {
00075 QCoreApplication::setOrganizationName( "LCG" );
00076 QCoreApplication::setOrganizationDomain( "AA" );
00077 QCoreApplication::setApplicationName( "ACE" );
00078 }
00079
00080 void MainWindow::loadGUISettings()
00081 {
00082 QSettings settings;
00083 settings.beginGroup( objectName() );
00084 if ( settings.value( "maximised", false ).toBool() )
00085 showMaximized();
00086 else
00087 {
00088 resize( settings.value( "size", QSize( 400, 400 ) ).toSize() );
00089 move( settings.value( "pos", QPoint( 200, 200) ).toPoint() );
00090 }
00091 settings.endGroup();
00092 }
00093
00094 void MainWindow::saveGUISettings()
00095 {
00096 QSettings settings;
00097 settings.beginGroup( objectName() );
00098 settings.setValue( "size", size() );
00099 settings.setValue( "pos", pos() );
00100 settings.setValue( "maximised", isFullScreen() );
00101 settings.endGroup();
00102 }
00103
00104 void MainWindow::closeEvent( QCloseEvent* event )
00105 {
00106 if ( !commitAll( true ) )
00107 {
00108 int ret = QMessageBox::warning(
00109 this,
00110 trUtf8("Warning"),
00111 trUtf8("Not all folders were committed successfully.\n"
00112 "Continue to quit?"),
00113 QMessageBox::Yes | QMessageBox::No,
00114 QMessageBox::No);
00115 if ( ret == QMessageBox::No )
00116 {
00117 event->ignore();
00118 return;
00119 }
00120 }
00121 saveGUISettings();
00122 event->accept();
00123 }
00124
00125 bool MainWindow::commitAll( bool ask, FolderTableModel* thisModelOnly )
00126 {
00127 bool ok( true );
00128 int ret;
00129 foreach ( const FolderTableModel* model, folderTableDockWidgets.keys() )
00130 {
00131 FolderTableModel* tempTableModel = const_cast< FolderTableModel* >( model );
00132 if ( thisModelOnly && tempTableModel != thisModelOnly )
00133 continue;
00134 if ( tempTableModel->getRootTableItem()->anyNew() )
00135 {
00136 if ( ask )
00137 {
00138 ret = QMessageBox::question(
00139 this,
00140 trUtf8( "Folder modified" ),
00141 QString( "Save changes to:\n%1?" ).arg( folderTableDockWidgets[ tempTableModel ]->windowTitle() ),
00142 QMessageBox::Yes | QMessageBox::No,
00143 QMessageBox::Yes );
00144 if ( ret == QMessageBox::No )
00145 continue;
00146 }
00147 setCursor( Qt::WaitCursor );
00148 if ( !tempTableModel->commit() )
00149 {
00150 ok = false;
00151 unsetCursor();
00152 ret = QMessageBox::warning(
00153 this,
00154 trUtf8( "Commit failed!" ),
00155 QString( "Could not commit\n%1\n\n%2" ).arg( folderTableDockWidgets[ tempTableModel ]->windowTitle() ).arg( "Continue to commit remaining folders?" ),
00156 QMessageBox::Yes | QMessageBox::No,
00157 QMessageBox::Yes );
00158 if ( ret == QMessageBox::No )
00159 break;
00160 }
00161 unsetCursor();
00162 }
00163 }
00164 slotCheckButtons();
00165 unsetCursor();
00166 return ok;
00167 }
00168
00169 void MainWindow::slotFolderCommitAll()
00170 {
00171 commitAll();
00172 }
00173
00174 void MainWindow::slotFolderCommit()
00175 {
00176 FolderTableModel* tempTableModel;
00177 if ( FolderTableView* tempFolderView = dynamic_cast< FolderTableView* >( QApplication::focusWidget() ) )
00178 {
00179 try
00180 {
00181 tempTableModel = tempFolderView->getFolderTableModel();
00182 }
00183 catch ( ... )
00184 {
00185 return;
00186 }
00187 setCursor( Qt::WaitCursor );
00188 if ( !tempTableModel->commit() )
00189 {
00190 QMessageBox::warning(
00191 this,
00192 folderTableDockWidgets[ tempTableModel ]->windowTitle(),
00193 trUtf8( "Commit failed!" ),
00194 QMessageBox::Ok,
00195 QMessageBox::Ok );
00196 }
00197 unsetCursor();
00198 }
00199 slotCheckButtons();
00200 }
00201
00202 void MainWindow::slotCheckButtons( bool force )
00203 {
00204 bool tBool( false );
00205 static QWidget* prevWidget = NULL;
00206
00207 if ( prevWidget == QApplication::focusWidget() )
00208 {
00209 if ( !force )
00210 {
00211 return;
00212 }
00213 }
00214 else
00215 {
00216 prevWidget = QApplication::focusWidget();
00217 }
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 FolderTableModel* tempTableModel = NULL;
00229
00230 if ( FolderTableView* tempFolderView = dynamic_cast< FolderTableView* >( prevWidget ) )
00231 {
00232 try
00233 {
00234 tempTableModel = tempFolderView->getFolderTableModel();
00235 action_FolderCommit->setEnabled( tempTableModel->getRootTableItem()->anyNew() );
00236
00237
00238 ;
00239 }
00240 catch ( ... )
00241 {
00242
00243 action_FolderCommit->setEnabled( false );
00244 }
00245 }
00246 else
00247 {
00248
00249 action_FolderCommit->setEnabled( false );
00250 }
00251
00252
00253 tBool = false;
00254 foreach ( const FolderTableModel* model, folderTableDockWidgets.keys() )
00255 {
00256 if ( model->getRootTableItem()->anyNew() )
00257 {
00258 tBool = true;
00259 break;
00260 }
00261 }
00262 action_FolderCommitAll->setEnabled( tBool );
00263 }
00264
00265 void MainWindow::removeFolder( FolderTableModel* theModel, QModelIndex treeIndex )
00266 {
00267 if ( treeIndex.isValid() )
00268 {
00269
00270 folderTableModels.remove( treeIndex );
00271
00272
00273 FolderTableDockWidget* dockWidget = folderTableDockWidgets.value( theModel );
00274 folderTableDockWidgets.remove( theModel );
00275 removeDockWidget( dockWidget );
00276 delete dockWidget;
00277 delete theModel;
00278 }
00279 else
00280 {
00281
00282 QHashIterator< QModelIndex, FolderTableModel* > i( folderTableModels );
00283 while ( i.hasNext() )
00284 {
00285 i.next();
00286 if ( i.value() == theModel )
00287 {
00288
00289 folderTableModels.remove( i.key() );
00290
00291
00292 FolderTableDockWidget* dockWidget = folderTableDockWidgets.value( theModel );
00293 folderTableDockWidgets.remove( theModel );
00294 removeDockWidget( dockWidget );
00295 delete dockWidget;
00296 delete theModel;
00297 return;
00298 }
00299 }
00300 }
00301 }
00302
00303 void MainWindow::slotRemoveFolder( FolderTableModel* theModel )
00304 {
00305 removeFolder( theModel );
00306 }
00307
00308 void MainWindow::slotConnectionDisconnect()
00309 {
00310 int ret;
00311 bool saveChanges( true );
00312
00313
00314 QWidget* tabWidget = tabWidget_Connections->currentWidget();
00315 if ( tabWidget == defaultConnectionTab )
00316 return;
00317 QTreeView* currentTreeView = tabWidget->findChild< QTreeView* >();
00318 FolderTreeModel* currentTreeModel = static_cast< FolderTreeModel* >( currentTreeView->model() );
00319
00320
00321 if ( currentTreeModel->isModified() )
00322 {
00323 ret = QMessageBox::information(
00324 this,
00325 trUtf8( "Folder(s) modified" ),
00326 trUtf8( "Commit changes before disconnection?" ),
00327 QMessageBox::Yes | QMessageBox::No,
00328 QMessageBox::Yes );
00329 if ( ret == QMessageBox::No )
00330 saveChanges = false;
00331 }
00332
00333
00334
00335 QHashIterator< QModelIndex, FolderTableModel* > i( folderTableModels );
00336 while ( i.hasNext() )
00337 {
00338 i.next();
00339
00340 if ( const_cast< FolderTreeModel* >( dynamic_cast< const FolderTreeModel* >( i.key().model() ) ) != currentTreeModel )
00341 continue;
00342
00343 if ( saveChanges && currentTreeModel->getModifiedFolders().contains( i.key() ) )
00344 {
00345 if ( !commitAll( false, i.value() ) )
00346 return;
00347 }
00348
00349 removeFolder( i.value(), i.key() );
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 }
00363
00364
00365
00366
00367 folderTreeViews.remove( currentTreeModel );
00368 delete currentTreeView;
00369
00370 connectionDialog->closeConnection( currentTreeModel->coolConnectionString );
00371 delete currentTreeModel;
00372
00373
00374 tabWidget_Connections->setUpdatesEnabled( false );
00375 tabWidget_Connections->removeTab( tabWidget_Connections->currentIndex() );
00376
00377 if ( tabWidget_Connections->count() == 0 )
00378 {
00379 tabWidget_Connections->addTab( defaultConnectionTab, trUtf8( "No current connection" ) );
00380 }
00381 tabWidget_Connections->setUpdatesEnabled( true );
00382 delete tabWidget;
00383 action_ConnectionDisconnect->setEnabled( connectionDialog->isConnected() );
00384
00385 }
00386
00387 void MainWindow::slotCreateFolderTree( cool::IDatabasePtr dbPtr, const QString connectionString )
00388 {
00389 int tabIndex = 0;
00390 QSettings settings;
00391 connectionCounter++;
00392
00393
00394 setCursor( Qt::WaitCursor );
00395 FolderTreeModel* folderTreeModel = new FolderTreeModel( dbPtr, connectionString );
00396 unsetCursor();
00397
00398 QWidget* tab_Connection = new QWidget();
00399
00400 tab_Connection->setObjectName( QString::fromUtf8( "DB Connect " ).append( QString::number( connectionCounter ) ) );
00401
00402 QHBoxLayout* hboxLayout = new QHBoxLayout( tab_Connection );
00403 hboxLayout->setObjectName( QString::fromUtf8( "hboxLayout" ).append( QString::number( connectionCounter ) ) );
00404 QTreeView* treeView_Folders = new QTreeView( tab_Connection );
00405 treeView_Folders->setModel( folderTreeModel );
00406 settings.beginGroup( "Preferences/FolderTrees" );
00407 if ( settings.value( "ExpandAll", true ).toBool() )
00408 {
00409 treeView_Folders->expandAll();
00410 }
00411 settings.endGroup();
00412 treeView_Folders->setObjectName( QString::fromUtf8( "COOL DB " ).append( QString::number( connectionCounter ) ) );
00413 treeView_Folders->show();
00414 folderTreeViews[ folderTreeModel ] = treeView_Folders;
00415
00416 hboxLayout->addWidget( treeView_Folders );
00417
00418
00419 tabWidget_Connections->setUpdatesEnabled( false );
00420 if ( tabWidget_Connections->count() == 1 && tabWidget_Connections->widget( 0 ) == defaultConnectionTab )
00421 {
00422 tabWidget_Connections->removeTab( 0 );
00423 }
00424
00425 tabIndex = tabWidget_Connections->addTab( tab_Connection, QString::fromUtf8( "DB Connect " ).append( QString::number( connectionCounter ) ) );
00426 tabWidget_Connections->setUpdatesEnabled( true );
00427
00428 tabWidget_Connections->setTabToolTip( tabIndex, connectionString );
00429
00430 QObject::connect( treeView_Folders, SIGNAL( doubleClicked( const QModelIndex& ) ), this, SLOT( slotCreateFolderTable( const QModelIndex& ) ) );
00431 action_ConnectionDisconnect->setEnabled( connectionDialog->isConnected() );
00432 }
00433
00434 void MainWindow::slotCreateFolderTable( const QModelIndex& fTreeIndex )
00435 {
00436
00437
00438
00439
00440 if ( folderTableModels.contains( fTreeIndex ) )
00441 {
00442 folderTableDockWidgets[ folderTableModels[ fTreeIndex ] ]->show();
00443 return;
00444 }
00445 const FolderTreeModel* folderTreeModel = static_cast< const FolderTreeModel* >( fTreeIndex.model() );
00446 const QString& fName = folderTreeModel->folderName( fTreeIndex );
00447 setCursor( Qt::WaitCursor );
00448 if ( !folderTreeModel->getCoolDBPtr()->existsFolder( fName.toStdString() ) )
00449 {
00450 unsetCursor();
00451 return;
00452 }
00453
00454 cool::IFolderPtr folderPtr = folderTreeModel->getCoolDBPtr()->getFolder( fName.toStdString() );
00455 folderOpenDialog->prepare( folderPtr, fName );
00456
00457 if ( !folderOpenDialog->exec() )
00458 {
00459 return;
00460 };
00461
00462 FolderTableModel* folderTableModel;
00463 try
00464 {
00465 folderTableModel = new FolderTableModel( folderPtr, folderOpenDialog->getSinceIOV(), cool::ValidityKeyMax, folderOpenDialog->getChannelSelection(), folderOpenDialog->getTag() );
00466 }
00467 catch ( ace_errors::EmptyFolder &e )
00468 {
00469 QMessageBox::warning(
00470 this,
00471 trUtf8( "Error" ),
00472 trUtf8( "Folder is empty!" ),
00473 QMessageBox::Ok,
00474 QMessageBox::Ok );
00475 unsetCursor();
00476 return;
00477 }
00478 catch ( ... )
00479 {
00480 QMessageBox::warning(
00481 this,
00482 trUtf8( "Unexpected Error" ),
00483 trUtf8( "Table could not be constructed!" ),
00484 QMessageBox::Ok,
00485 QMessageBox::Ok );
00486 unsetCursor();
00487 return;
00488 }
00489
00490 FolderTableDockWidget* dockWidget_Table = new FolderTableDockWidget( this );
00491 dockWidget_Table->setWindowTitle( trUtf8( "%1:%2[*]" ).arg( folderTableModels.size() ).arg( fName ) );
00492
00493 dockWidget_Table->setToolTip( folderOpenDialog->getFolderCharacteristics() );
00494 dockWidget_Table->setTableModel( folderTableModel );
00495 QWidget* dockWidgetContents_Table = new QWidget( dockWidget_Table );
00496 dockWidgetContents_Table->setObjectName( QString::fromUtf8( "dockWidgetContents_Table" ).append( QString::number( folderTableModels.size() ) ) );
00497 QVBoxLayout* vboxLayout = new QVBoxLayout( dockWidgetContents_Table );
00498 vboxLayout->setObjectName( QString::fromUtf8( "vboxLayout" ).append( QString::number( folderTableModels.size() ) ) );
00499 vboxLayout->setContentsMargins( 0, 0, 0, 0 );
00500 FolderTableView* tableView_Folder = new FolderTableView( dockWidgetContents_Table, folderTableModel );
00501 tableView_Folder->setObjectName( dockWidget_Table->windowTitle() );
00502 tableView_Folder->setMinimumSize( QSize( 400, 0 ) );
00503 tableView_Folder->show();
00504 folderTableModels[ fTreeIndex ] = folderTableModel;
00505 folderTableDockWidgets[ folderTableModel ] = dockWidget_Table;
00506 vboxLayout->addWidget( tableView_Folder );
00507
00508 dockWidget_Table->setWidget( dockWidgetContents_Table );
00509
00510
00511 QObject::connect( folderTableModel, SIGNAL( modelChanged( const FolderTableModel*, bool ) ), this, SLOT( slotTableModified( const FolderTableModel*, bool ) ) );
00512 QObject::connect( tableView_Folder, SIGNAL( checkButtons( bool ) ), this, SLOT( slotCheckButtons( bool ) ) );
00513 QObject::connect( tableView_Folder, SIGNAL( updateFilterTarget( FolderTableModel*, QString ) ), filterBuilderDockWidget->filterBuilder, SLOT( slotUpdateFilter( FolderTableModel*, QString ) ) );
00514 QObject::connect( dockWidget_Table, SIGNAL( folderTableDockWidgetClose( FolderTableModel* ) ), filterBuilderDockWidget->filterBuilder, SLOT( slotClearCurrentTableModel( FolderTableModel* ) ) );
00515 QObject::connect( dockWidget_Table, SIGNAL( folderTableDockWidgetClose( FolderTableModel* ) ), this, SLOT( slotRemoveFolder( FolderTableModel* ) ) );
00516 QObject::connect( filterBuilderDockWidget->filterBuilder, SIGNAL( applyClicked( FolderTableModel*, QList< int > ) ), tableView_Folder, SLOT( slotApplyFilter( FolderTableModel*, QList< int > ) ) );
00517 QObject::connect( dockWidget_Table, SIGNAL( changeFocusToTable() ), tableView_Folder, SLOT( slotSetFocus() ) );
00518
00519
00520
00521 addDockWidget( Qt::RightDockWidgetArea, dockWidget_Table );
00522 unsetCursor();
00523 dockWidget_Table->setFocus();
00524 slotCheckButtons();
00525 }
00526
00527 void MainWindow::slotConnectionOpen()
00528 {
00529 connectionDialog->exec();
00530 }
00531
00532 void MainWindow::slotFolderFilter( bool enabled )
00533 {
00534 if ( enabled )
00535 {
00536 filterBuilderDockWidget->show();
00537 }
00538 else
00539 {
00540 filterBuilderDockWidget->hide();
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562 }
00563
00564 void MainWindow::slotTableModified( const FolderTableModel* modifiedModel, const bool changed )
00565 {
00566 folderTableDockWidgets[ modifiedModel ]->setWindowModified( changed );
00567 QHashIterator< QModelIndex, FolderTableModel* > i( folderTableModels );
00568 while ( i.hasNext() )
00569 {
00570 i.next();
00571 if ( modifiedModel == i.value() )
00572 {
00573
00574 FolderTreeModel* folderTreeModel = const_cast< FolderTreeModel* >( dynamic_cast< const FolderTreeModel* >( i.key().model() ) );
00575 folderTreeModel->emitDataChanged( i.key(), changed );
00576 break;
00577 }
00578 }
00579 }
00580
00581 void MainWindow::testRoutine()
00582 {
00583
00584
00585
00586 cool::DatabaseId dbId("ACETEST1/TEST");
00587 cool::IDatabasePtr dbPtr;
00588 if ( !cool::openDatabase( dbId, dbPtr ) )
00589 {
00590 qDebug() << "Oops! test database could not be opened.";
00591 return;
00592 }
00593 cool::IFolderPtr f1 = dbPtr->getFolder( "/folder_1" );
00594 qDebug() << "testRoutine: Opened test database successful. Folder retrieved as well." ;
00595 }
00596
00597 int main(int argc, char *argv[])
00598 {
00599 QApplication app(argc, argv);
00600 Q_INIT_RESOURCE(icons);
00601 MainWindow mainWin;
00602 mainWin.show();
00603 return app.exec();
00604 }
00605
00606 #else
00607 #include <iostream>
00608
00609 int main( int, char** )
00610 {
00611 std::cout << "ACE is not supported on MacOSX!" << std::endl;
00612 return 1;
00613 }
00614
00615 #endif
00616
00617 #else
00618 #include <iostream>
00619
00620 int main( int, char** )
00621 {
00622 std::cout << "ACE is not supported on Windows!" << std::endl;
00623 return 1;
00624 }
00625
00626 #endif