DumontEXE 0.0.1
DumontEXE.cpp
00001 /* ***************************************************************************
00002 **
00003 ** Copyright (C) 2007 Lorimark Solutions, LLC. All rights reserved.
00004 **
00005 ** This file is part of the DumontEXE Scripting Extension Kit
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://dumont.showoff-db.org/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://dumont.showoff-db.org/licensing.html 
00017 ** or contact the sales department at sales@lorimarksolutions.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ** author: Mark Petryk ~ Lorimark Solutions, LLC
00023 ** **************************************************************************/
00024 
00025 #include <QDebug>
00026 #include "DumontEXE.h"
00027 #include <qwinhookmgr.h>
00028 #include "DumontFactory.h"
00029 
00030 #include "taskmonitor.h"
00031 
00032 #include <QClipboard>
00033 #include <QApplication>
00034 #include <QMessageBox>
00035 #include <QxtLogger.h>
00036 #include <objbase.h>
00037 #include <QPointer>
00038 #include <QTimerEvent>
00039 #include <QSystemTrayIcon>
00040 #include <QAbstractItemModel>
00041 #include <QDesktopWidget>
00042 #include <QProcess>
00043 #include <QFile>
00044 #include <QShowEvent>
00045 #include <QFileDialog>
00046 
00047 #include "cmcApplication.h"
00048 #include "cmcApplications.h"
00049 #include "cmcConversation.h"
00050 #include "cmcCategoryDefs.h"
00051 #include "cmcCategoryDef.h"
00052 #include "cmcFieldDefs.h"
00053 #include "cmcFieldDef.h"
00054 #include "cmcConnectionDefs.h"
00055 #include "cmcConnectionDef.h"
00056 #include "cmcFormDefs.h"
00057 #include "cmcFormDef.h"
00058 #include "cmcViewDefs.h"
00059 #include "cmcViewDef.h"
00060 #include "cmcTreeModel.h"
00061 #include "cmcFormScript.h"
00062 
00063 #include "ModuleInstance.h"
00064 
00065 #define AUTO_QUIT 10
00066 
00067 using namespace cmcDatabaseApi;
00068 
00069 // cmcApplications g_cmcApplications;
00070 
00071 QPointer<winDumontEXE> g_mainWin;
00072 
00073 winDumontEXE * mainWin()
00074 {
00075   if( g_mainWin.isNull() ) exit(0);
00076   return( g_mainWin );
00077 }
00078 
00079 DumontEXE * DumontEXE::createObject( QObject * parent )
00080 {
00081   DumontEXE * object = g_mainWin-> findChild<DumontEXE*>();
00082 
00083   if( !object )
00084        object = new DumontEXE(g_mainWin);
00085 //  else
00086 //    qDebug( "DumontEXE object already exists" );
00087 
00088 //  qDebug( "dexe p0 %p", object-> parent() );
00089 
00090   return( object );
00091 
00092 //  return( new DumontEXE(parent) );
00093 }
00094 
00095 DumontEXE::DumontEXE( QObject * parent )
00096 :
00097   DumontObject( parent )
00098 {
00099 //  TRACE_FUNCTION
00100 }
00101 
00102 DumontEXE::~DumontEXE()
00103 {
00104 //  TRACE_FUNCTION
00105 }
00106 
00107 QString DumontEXE::version()
00108 {
00109   return( DUMONTEXE_VERSION );
00110 }
00111 
00112 winDumontEXE * DumontEXE::mainWindow()
00113 {
00114   return( mainWin() );
00115 }
00116 
00117 void DumontEXE::textFile( const QString & fileName, const QString & data )
00118 {
00119   QFile file(fileName);
00120   if( file.open(QIODevice::WriteOnly) )
00121     file.write( data.toAscii() );
00122 }
00123 
00124 void DumontEXE::appendTextFile( const QString & fileName, const QString & data )
00125 {
00126   QFile file(fileName);
00127   file.open(QIODevice::Append);
00128   file.write( data.toAscii() );
00129 }
00130 
00131 
00132 
00133 
00134 
00135 QxtLogger * DumontEXE::log()
00136 {
00137   return( qxtLoggerManager-> getLogger("dumont") );
00138 }
00139 
00140 #include <QDockWidget>
00141 
00142 QxtLoggerWindow * DumontEXE::logWindow
00143 (
00144   const QString & name,
00145   bool show,
00146   bool clear,
00147   long x,
00148   long y,
00149   long w,
00150   long h
00151 )
00152 {
00153   QxtLoggerWindow * retVal = m_loggerWindows[name];
00154 
00155   if( !retVal )
00156   {
00157     QDockWidget * dock = new QDockWidget(g_mainWin);
00158     dock-> setObjectName(name);
00159     QFont font;
00160     font.setFamily(QString::fromUtf8("Courier New"));
00161     dock-> setFont(font);
00162     dock-> setFloating(false);
00163     dock-> setWindowTitle(name);
00164 
00165     QWidget * dockContents = new QWidget(dock);
00166     dockContents-> setObjectName( name + "Contents" );
00167 
00168     QGridLayout * gridLayout = new QGridLayout(dockContents);
00169     gridLayout-> setObjectName(QString::fromUtf8("gridLayout"));
00170     gridLayout-> setHorizontalSpacing(0);
00171     gridLayout-> setVerticalSpacing(0);
00172     gridLayout-> setContentsMargins(0,0,0,0);
00173 
00174     retVal = new QxtLoggerWindow(name, dockContents, x, y, w, h );
00175 
00176     gridLayout-> addWidget( retVal, 0, 0, 1, 1 );
00177 
00178     dock-> setWidget(dockContents);
00179     g_mainWin-> addDockWidget( Qt::BottomDockWidgetArea,dock );
00180 
00181     g_mainWin-> mnuView-> addAction( dock-> toggleViewAction() );
00182 
00183     m_loggerWindows[name] = retVal;
00184 
00185     if( m_loggerWindows.count() > 1 )
00186     {
00187       g_mainWin-> tabifyDockWidget
00188       (
00189         qobject_cast<QDockWidget*>(m_loggerWindows.values().at( m_loggerWindows.count()-1 )-> parent()-> parent()),
00190         qobject_cast<QDockWidget*>(m_loggerWindows.values().at( m_loggerWindows.count()-2 )-> parent()-> parent())
00191       );
00192     }
00193   }
00194 
00195   if( show  ) retVal-> show();
00196   if( clear ) retVal-> clear();
00197 
00198   return( retVal );
00199 }
00200 
00201 void DumontEXE::debugClear()
00202 {
00203   qxtLoggerManager-> getRootLogger()-> clear();
00204 }
00205 
00206 void DumontEXE::debug( const QString & msg )
00207 {
00208   qDebug( msg.toAscii().data() );
00209 }
00210 
00211 void DumontEXE::warning( const QString & msg )
00212 {
00213   qWarning( msg.toAscii().data() );
00214 }
00215 
00216 void DumontEXE::critical( const QString & msg )
00217 {
00218   qCritical( msg.toAscii().data() );
00219 }
00220 
00221 void DumontEXE::fatal( const QString & msg )
00222 {
00223   qFatal( msg.toAscii().data() );
00224 }
00225 
00226 cmcApplications * DumontEXE::applications()
00227 {
00228 //  TRACE_FUNCTION
00229   return( cmcObject::apps() );
00230 }
00231 
00232 cmcDatabaseApi::cmcApplication * DumontEXE::application( const QString & databaseName )
00233 {
00234   return( cmcObject::apps()-> application( databaseName ) );
00235 }
00236 
00237 cmcDatabaseApi::cmcApplication * DumontEXE::application( long index )
00238 {
00239   return( cmcObject::apps()-> application( index ) );
00240 }
00241 
00242 cmcDatabaseApi::cmcApplication * DumontEXE::app( IDispatch * dispatch )
00243 {
00244 //  TRACE_FUNCTION
00245   return( new cmcDatabaseApi::cmcApplication(dispatch) );
00246 }
00247 
00248 cmcDatabaseApi::cmcForm * DumontEXE::form( IDispatch * dispatch )
00249 {
00250   return( new cmcDatabaseApi::cmcForm(dispatch) );
00251 }
00252 
00253 QString DumontEXE::dateTimeStamp( long length )
00254 {
00255   return( cmcDatabaseApi::dateTimeStamp(length) );
00256 }
00257 
00258 QString DumontEXE::dateTimeStamp( const QDateTime & dateTime, long length )
00259 {
00260   return( cmcDatabaseApi::dateTimeStamp(dateTime,length) );
00261 }
00262 
00263 QString DumontEXE::dateTimeStamp( const QString & delimiter )
00264 {
00265   return( cmcDatabaseApi::dateTimeStamp(delimiter) );
00266 }
00267 
00268 static QString format_guid( const QString formatString, const QUuid & id )
00269 {
00270   QString retVal = formatString
00271       .arg( ((GUID)id).Data1,    8, 16, QChar('0')  )
00272       .arg( ((GUID)id).Data2,    4, 16, QChar('0')  )
00273       .arg( ((GUID)id).Data3,    4, 16, QChar('0')  )
00274       .arg( ((GUID)id).Data4[0], 2, 16, QChar('0')  )
00275       .arg( ((GUID)id).Data4[1], 2, 16, QChar('0')  )
00276       .arg( ((GUID)id).Data4[2], 2, 16, QChar('0')  )
00277       .arg( ((GUID)id).Data4[3], 2, 16, QChar('0')  )
00278       .arg( ((GUID)id).Data4[4], 2, 16, QChar('0')  )
00279       .arg( ((GUID)id).Data4[5], 2, 16, QChar('0')  )
00280       .arg( ((GUID)id).Data4[6], 2, 16, QChar('0')  )
00281       .arg( ((GUID)id).Data4[7], 2, 16, QChar('0')  )
00282   ;
00283 
00284   return( retVal );
00285 
00286 }
00287 
00288 QString DumontEXE::guid( const QUuid & id, long format, bool ucase )
00289 {
00290   QString retVal = "guid: unknown format";
00291 
00292   switch( format )
00293   {
00294     case rawDataGuid:
00295     {
00296       retVal = format_guid("%1%2%3%4%5%6%7%8%9%10%11", id);
00297       break;
00298     }
00299 
00300     case registryGuid:
00301     {
00302       retVal = format_guid("{%1-%2-%3-%4%5-%6%7%8%9%10%11}", id);
00303       if( ucase )
00304         retVal = retVal.toUpper();
00305       break;
00306     }
00307 
00308     case headerProtectGuid:
00309     {
00310       retVal = format_guid("_%1_%2_%3_%4%5_%6%7%8%9%10%11", id);
00311       if( ucase )
00312         retVal = retVal.toUpper();
00313       break;
00314     }
00315 
00316     case oleCreateGuid:
00317     {
00318       retVal = "// " + id.toString();
00319       retVal.append( format_guid("\nIMPLEMENT_OLECREATE(<<class>>, <<external_name>>, 0x%1, 0x%2, 0x%3, 0x%4, 0x%5, 0x%6, 0x%7, 0x%8, 0x%9, 0x%10, 0x%11);", id) );
00320       break;
00321     }
00322 
00323     case defGuid:
00324     {
00325       retVal = "//" + id.toString();
00326       retVal.append( format_guid("\nDEFINE_GUID(<<name>>, 0x%1, 0x%2, 0x%3, 0x%4, 0x%5, 0x%6, 0x%7, 0x%8, 0x%9, 0x%10, 0x%11);", id) );
00327       break;
00328     }
00329 
00330     case staticGuid:
00331     {
00332       retVal = "//" + id.toString();
00333       retVal.append( format_guid("\nstatic const GUID <<name>> = { 0x%1, 0x%2, 0x%3, { 0x%4, 0x%5, 0x%6, 0x%7, 0x%8, 0x%9, 0x%10, 0x%11 } };", id) );
00334       break;
00335     }
00336 
00337   }
00338 
00339   return( retVal );
00340 
00341 }
00342 
00343 QString DumontEXE::guid( const QString & id, long format, bool ucase )
00344 {
00345   return( guid( QUuid(id), format, ucase ) );
00346 }
00347 
00348 QString DumontEXE::guid( long format, bool ucase )
00349 {
00350   return( guid( QUuid::createUuid(), format, ucase ) );
00351 }
00352 
00353 QString DumontEXE::dq( const QString & string )
00354 {
00355   QString retVal = string;
00356 
00357   retVal = retVal.replace( "\"", "\"\"" );
00358 
00359   return( "\"" + retVal + "\"" );
00360 }
00361 
00362 
00363 bool DumontEXE::run
00364 (
00365   const QString program,
00366   const QString argument1,
00367   const QString argument2,
00368   const QString argument3,
00369   const QString argument4,
00370   const QString argument5,
00371   const QString argument6,
00372   const QString argument7,
00373   const QString argument8
00374 )
00375 {
00376   return( false );
00377 }
00378 
00379 
00380 void DumontEXE::cliptext( const QString & value )
00381 {
00382   QApplication::clipboard()-> setText( value );
00383 }
00384 
00385 QString DumontEXE::cliptext( void )
00386 {
00387   return( QApplication::clipboard()-> text() );
00388 }
00389 
00390 
00391 
00392 
00393 
00394 QString DumontEXE::fileOpenDialog
00395 (
00396   const QString & caption,
00397   const QString & dir,
00398   const QString & filter
00399 )
00400 {
00401   return( QFileDialog::getOpenFileName( NULL, caption, QString(dir).replace("\\","/"), filter ).replace("/","\\") );
00402 }
00403 
00404 #include <QCryptographicHash>
00405 
00406 QString DumontEXE::md5( const QString & data )
00407 {
00408   QCryptographicHash ch(QCryptographicHash::Md5);
00409 
00410   QByteArray ba;
00411 
00412   ba.append(data);
00413 
00414   ch.addData(ba);
00415 
00416   return( QString(ba.toHex()) );
00417 }
00418 
00419 long DumontEXE::crc16( const QString & data )
00420 {
00421   if( data == "" )
00422     return(0);
00423 
00424   QByteArray ba;
00425 
00426   ba.append(data);
00427 
00428   return( qChecksum(ba.constData(),ba.length()) );
00429 }
00430 
00431 long DumontEXE::crc32( const QString & data )
00432 {
00433   long rv1 = crc16(data);
00434 
00435   QString d2;
00436   for( int i=0; i<data.length(); i++ )
00437     d2.append( data.at(data.length()-i) );
00438 
00439   long rv2 = crc16(d2);
00440 
00441   return( (rv1<<16) + rv2 );
00442 }
00443 
00444 QString DumontEXE::compress( const QString & data, int level )
00445 {
00446   QByteArray ba;
00447 
00448   ba.append(data);
00449 
00450   ba = qCompress(ba,level);
00451 
00452   return( QString(ba.toHex()) );
00453 }
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 
00464 
00465 
00466 
00467 void statusBar( const QString & message )
00468 {
00469   if( g_mainWin )
00470   if( g_mainWin-> statusBar() )
00471       g_mainWin-> statusBar()-> showMessage( message );
00472 }
00473 
00474 
00475 
00476 
00477 
00478 
00479 
00480 
00481 
00482 
00483 
00484 
00485 
00486 /**
00487  ** The constructor initializes the environment for the first application.
00488  **
00489  */
00490 winDumontEXE::winDumontEXE()
00491 : m_cmcExe(NULL)
00492 {
00493   /*
00494   ** Build the ui component
00495   **
00496   */
00497   setupUi(this);
00498 
00499   if( qApp-> arguments().contains("-register",Qt::CaseInsensitive) )
00500     return;
00501 
00502   mnuView-> addAction( dockApplications-> toggleViewAction() );
00503   mnuView-> addAction( dockProperties->   toggleViewAction() );
00504   mnuView-> addAction( dockMessages->     toggleViewAction() );
00505   mnuView-> addSeparator();
00506 
00507   g_mainWin = this;
00508 
00509   startTimer( 1000 );
00510 
00511   stm = new QMenu(this);
00512   stm-> addAction(actDumontShow);
00513   stm-> addSeparator();
00514   stm-> addAction(actFileQuit);
00515 
00516   sti = new QSystemTrayIcon( QIcon(":/SystemTrayIcon"), this );
00517   sti-> setContextMenu(stm);
00518   sti-> setToolTip( "Dumont" );
00519   sti-> show();
00520 
00521   readSettings();
00522 
00523   // qDebug( "arguments %s", qPrintable(qApp-> arguments().join("\n")) );
00524 
00525 
00526 //  treeCommence-> setModel( new cmcApplicationsModel() );
00527 
00528 } // endfirstMainWindow::firstMainWindow()
00529 
00530 winDumontEXE::~winDumontEXE()
00531 {
00532 //  TRACE_FUNCTION
00533 
00534   writeSettings();
00535 
00536   g_mainWin = NULL;
00537 
00538 // QMessageBox::information( NULL, objectName(), "shutting down" );
00539 
00540 }
00541 
00542 void winDumontEXE::readSettings()
00543 {
00544   QSettings settings;
00545   QPoint pos = settings.value( "/" + objectName() + "/pos",  QPoint(200, 200)).toPoint();
00546   QSize size = settings.value( "/" + objectName() + "/size", QSize(400,  400)).toSize();
00547 
00548   move(pos);
00549   resize(size);
00550 
00551   restoreState( settings.value("/" + objectName() + "/state").toByteArray() );
00552 
00553 }
00554 
00555 void winDumontEXE::writeSettings()
00556 {
00557   QSettings settings;
00558 
00559   settings.setValue( "/" + objectName() + "/pos",  pos()  );
00560   settings.setValue( "/" + objectName() + "/size", size() );
00561 
00562   settings.setValue( "/" + objectName() + "/state", saveState() );
00563 
00564 }
00565 
00566 void winDumontEXE::showEvent( QShowEvent * event )
00567 {
00568 }
00569 
00570 void winDumontEXE::closeEvent( QCloseEvent * event )
00571 {
00572 }
00573 
00574 void winDumontEXE::on_actFileOpen_triggered()
00575 {
00576 //  m_cmcEXE.append( new QCommenceEXE() );
00577 
00578 }
00579 
00580 void winDumontEXE::on_actViewTaskMonitor_triggered()
00581 {
00582   dlgTaskMonitor * win = new dlgTaskMonitor();
00583 
00584   win-> show();
00585 }
00586 
00587 void winDumontEXE::on_actViewLogWindow_triggered()
00588 {
00589   QDockWidget * dock = new QDockWidget( "new dock widget", this );
00590   dock-> show();
00591 
00592   QMainWindow * window = new QMainWindow(dock);
00593 
00594   dock-> setWidget( window );
00595 
00596   addDockWidget( Qt::RightDockWidgetArea, dock );
00597 
00598 }
00599 
00600 void winDumontEXE::on_actViewRefresh_triggered()
00601 {
00602 //  treeCommence-> reset();
00603 }
00604 
00605 void winDumontEXE::on_actFileQuit_triggered()
00606 {
00607   qApp-> quit();
00608 }
00609 
00610 void winDumontEXE::on_actHelpAbout_triggered()
00611 {
00612   QMessageBox::information
00613   ( 
00614     this, 
00615     "DumontEXE", 
00616     "Version: " + 
00617     QString(DUMONTEXE_VERSION) + 
00618     "\n\nshowoff-db.org" 
00619   );
00620 }
00621 
00622 
00623 void winDumontEXE::on_actDumontShow_triggered()
00624 {
00625   show();
00626 
00627   cmcApplications * apps = cmcObject::apps();
00628 
00629   if( apps-> count() > 0 ) 
00630   {
00631 //    cmcDatabaseApi::cmcApplication * app = apps-> application(0);
00632 
00633 //    treeCommence-> setModel( qobject_cast<QAbstractItemModel*>(app-> applicationModel()) );
00634 
00635   }
00636 //  treeCommence-> setModel( new cmcApplicationsModel() );
00637 
00638 }
00639 
00640 
00641 enum {
00642   twApplication = QTreeWidgetItem::UserType + 1,
00643   twAgents,
00644   twCategories,
00645   twViews,
00646   twDesktops,
00647   twScripts,
00648   twTriggers,
00649   twLogfile,
00650   twSettings,
00651   twCategory,
00652   twFields,
00653   twConnections,
00654   twForms,
00655   twField,
00656   twConnection,
00657   twForm,
00658   twView
00659 };
00660 
00661 void winDumontEXE::on_dockApplications_visibilityChanged( bool visible )
00662 {
00663   if( !visible ) return;
00664 
00665   QTreeWidget * tree = applicationsTree;
00666 
00667   tree-> setColumnCount( 2 );
00668 
00669   /*
00670   ** Delete any existing applications
00671   **
00672   */
00673   QTreeWidgetItemIterator it(tree);
00674   while( *it ) delete *it;
00675 
00676   /*
00677   ** Loop through all the applications and register them
00678   **  in the tree view.
00679   **
00680   */
00681   for( int i = 0; i < cmcObject::apps()-> children().count(); i++ )
00682   {
00683     cmcDatabaseApi::cmcApplication * app = cmcObject::apps()-> application( i );
00684 
00685     QTreeWidgetItem * appItem =
00686       new QTreeWidgetItem( tree,
00687         QStringList()
00688           << app-> databaseName()
00689           << app-> databaseDirectory(),
00690           twApplication
00691     );
00692 
00693     new QTreeWidgetItem( appItem, QStringList("Agents"),     twAgents     );
00694     new QTreeWidgetItem( appItem, QStringList("Categories"), twCategories );
00695     new QTreeWidgetItem( appItem, QStringList("Views"),      twViews      );
00696     new QTreeWidgetItem( appItem, QStringList("Desktops"),   twDesktops   );
00697     new QTreeWidgetItem( appItem, QStringList("Scripts"),    twScripts    );
00698     new QTreeWidgetItem( appItem, QStringList("Triggers"),   twTriggers   );
00699     new QTreeWidgetItem( appItem, QStringList("Logfile"),    twLogfile    );
00700     new QTreeWidgetItem( appItem, QStringList("Settings"),   twSettings   );
00701 
00702   }
00703 
00704 }
00705 
00706 QTreeWidgetItem * findItemType( QTreeWidgetItem * parent, int itemType )
00707 {
00708   for( int i=0; i<parent-> childCount(); i++ )
00709   {
00710     if( parent-> child(i)-> type() == itemType )
00711     {
00712       return( parent-> child(i) );
00713     }
00714   }
00715 
00716   return( NULL );
00717 }
00718 
00719 void removeChildren( QTreeWidgetItem * item )
00720 {
00721   while( item-> childCount() )
00722     item-> takeChild(0);
00723 
00724 }
00725 
00726 cmcDatabaseApi::cmcApplication * getApplication( QTreeWidgetItem * item )
00727 {
00728   if( !item ) return(NULL);
00729 
00730   if( item-> type() == twApplication )
00731   {
00732     return( cmcObject::apps()-> application( item-> text(0) ) );
00733   }
00734 
00735   return( getApplication(item-> parent()) );
00736 }
00737 
00738 QString getCategoryName( QTreeWidgetItem * item )
00739 {
00740   if( !item ) return( "" );
00741 
00742   if( item-> type() == twConnection )
00743   {
00744     return( item-> text(0).split(" -> ")[1] );
00745   }
00746 
00747   if( item-> type() == twCategory )
00748   {
00749     return( item-> text(0) );
00750   }
00751 
00752   return( getCategoryName(item-> parent()) );
00753 }
00754 
00755 
00756 void winDumontEXE::on_applicationsTree_itemExpanded( QTreeWidgetItem * item )
00757 {
00758   cmcDatabaseApi::cmcApplication * app =
00759     getApplication( item );
00760 
00761   if( !app ) return;
00762 
00763   switch( item-> type() ) 
00764   {
00765     case twApplication:
00766     {
00767       QTreeWidgetItem * categories = findItemType( item, twCategories );
00768 
00769       if( categories )
00770       {
00771         removeChildren( categories );
00772 
00773         for( int i=0; i<app-> categoryDefs()-> count(); i++ )
00774         {
00775           QTreeWidgetItem * item =
00776             new QTreeWidgetItem( categories, 
00777               QStringList() <<
00778               app-> categoryDefs()-> get(i)-> categoryName(),
00779               twCategory );
00780 
00781           new QTreeWidgetItem( item, QStringList("Fields"),      twFields      );
00782           new QTreeWidgetItem( item, QStringList("Connections"), twConnections );
00783           new QTreeWidgetItem( item, QStringList("Forms"),       twForms       );
00784           new QTreeWidgetItem( item, QStringList("Views"),       twViews       );
00785 
00786         }
00787 
00788       }
00789 
00790 
00791       break;
00792     }
00793 
00794     case twAgents:
00795     {
00796       break;
00797     }
00798 
00799     case twCategories:
00800     {
00801       break;
00802     }
00803 
00804     case twViews:
00805     {
00806       break;
00807     }
00808 
00809     case twDesktops:
00810     {
00811       break;
00812     }
00813 
00814     case twScripts:
00815     {
00816       break;
00817     }
00818 
00819     case twTriggers:
00820     {
00821       break;
00822     }
00823 
00824     case twLogfile:
00825     {
00826       break;
00827     }
00828 
00829     case twSettings:
00830     {
00831       break;
00832     }
00833 
00834     case twConnection:
00835     case twCategory:
00836     {
00837       QTreeWidgetItem * fields = findItemType( item, twFields );
00838 
00839       QString categoryName = getCategoryName( item );
00840 
00841       if( fields )
00842       {
00843         removeChildren( fields );
00844 
00845         cmcDatabaseApi::cmcFieldDefs * fieldDefs = 
00846           app-> categoryDefs()-> get( categoryName )-> fieldDefs();
00847 
00848         if( !fieldDefs ) return;
00849 
00850         for( int i=0; i<fieldDefs-> count(); i++ )
00851         {
00852 //          QTreeWidgetItem * item =
00853             new QTreeWidgetItem( fields, 
00854               QStringList() <<
00855               fieldDefs-> get(i)-> fieldName(),
00856               twField );
00857         }
00858 
00859       }
00860 
00861 
00862 
00863 
00864       QTreeWidgetItem * connections = findItemType( item, twConnections );
00865 
00866       if( connections )
00867       {
00868         removeChildren( connections );
00869 
00870         cmcDatabaseApi::cmcConnectionDefs * connectionDefs = 
00871           app-> categoryDefs()-> get( categoryName )-> connectionDefs();
00872 
00873         if( !connectionDefs ) return;
00874 
00875         for( int i=0; i<connectionDefs-> count(); i++ )
00876         {
00877           QTreeWidgetItem * connection = 
00878           new QTreeWidgetItem( connections,
00879             QStringList() <<
00880             connectionDefs-> get(i)-> name(),
00881             twConnection );
00882 
00883           new QTreeWidgetItem( connection, QStringList("Fields"),      twFields      );
00884           new QTreeWidgetItem( connection, QStringList("Connections"), twConnections );
00885           new QTreeWidgetItem( connection, QStringList("Forms"),       twForms       );
00886           new QTreeWidgetItem( connection, QStringList("Views"),       twViews       );
00887 
00888         }
00889 
00890       }
00891 
00892 
00893       QTreeWidgetItem * forms = findItemType( item, twForms );
00894 
00895       if( forms )
00896       {
00897         removeChildren( forms );
00898 
00899         cmcDatabaseApi::cmcFormDefs * formDefs = 
00900           app-> categoryDefs()-> get( categoryName )-> formDefs();
00901 
00902         if( !formDefs ) return;
00903 
00904         for( int i=0; i<formDefs-> count(); i++ )
00905         {
00906           new QTreeWidgetItem( forms,
00907             QStringList() <<
00908             formDefs-> get(i)-> name(),
00909             twForm );
00910         }
00911 
00912       }
00913 
00914 
00915 
00916       QTreeWidgetItem * views = findItemType( item, twViews );
00917 
00918       if( views )
00919       {
00920         removeChildren( views );
00921 
00922         cmcDatabaseApi::cmcViewDefs * viewDefs = 
00923           app-> categoryDefs()-> get( categoryName )-> viewDefs();
00924 
00925         if( !viewDefs ) return;
00926 
00927         for( int i=0; i<viewDefs-> count(); i++ )
00928         {
00929           new QTreeWidgetItem( views,
00930             QStringList() <<
00931             viewDefs-> get(i)-> name(),
00932             twView );
00933         }
00934 
00935       }
00936 
00937 
00938 
00939       break;
00940     }
00941 
00942   }
00943 
00944 }
00945 
00946 void winDumontEXE::DumpCategoryFields( cmcDatabaseApi::cmcCategoryDef * categoryDef )
00947 {
00948   propertyText-> appendPlainText( "Fields for " + categoryDef-> categoryName() );
00949   propertyText-> appendPlainText( "idx  Name                 Type       Style  Mand Recu Chars Comment" );
00950   propertyText-> appendPlainText( "----+--------------------+----------+------+----+----+-----+-------------" );
00951 
00952   for( int j = 0; j < categoryDef-> fieldDefs()-> count(); j++ )
00953   {
00954     cmcDatabaseApi::cmcFieldDef * fieldDef = 
00955       categoryDef-> fieldDefs(j);
00956 
00957      propertyText-> appendPlainText
00958      ( // idx  name  type styl man  recc char comment
00959        QString("%1 %2 %3 %4 %5 %6 %7 %8")
00960        .arg(j+1,4)
00961        .arg(fieldDef-> name(),-20)
00962        .arg(fieldDef-> typeName(),-10)
00963        .arg(fieldDef-> isSelection()? "Combox":"Radio",-6)
00964        .arg(fieldDef-> isMandatory()? "Yes":"No",-4)
00965        .arg(fieldDef-> isRecurring()? "Yes":"No",-4)
00966        .arg(fieldDef-> maxChars(),5)
00967        .arg(fieldDef-> defaultString())
00968      );
00969   }
00970 }
00971 
00972 void winDumontEXE::DumpCategoryConnections( cmcDatabaseApi::cmcCategoryDef * categoryDef )
00973 {
00974   propertyText-> appendPlainText( "Connections for " + categoryDef-> categoryName() );
00975   propertyText-> appendPlainText( "idx  Name                 toCategory"            );
00976   propertyText-> appendPlainText( "----+--------------------+--------------------"  );
00977 
00978   for( int j = 0; j < categoryDef-> connectionDefs()-> count(); j++ )
00979   {
00980     cmcDatabaseApi::cmcConnectionDef * connectionDef = 
00981       categoryDef-> connectionDefs(j);
00982 
00983      propertyText-> appendPlainText
00984      ( // idx  name  type styl man  recc char comment
00985        QString("%1 %2 %3")
00986        .arg(j+1,4)
00987        .arg(connectionDef-> conName(),-20)
00988        .arg(connectionDef-> toCategory(),-20)
00989      );
00990   }
00991 
00992 }
00993 
00994 
00995 void winDumontEXE::on_applicationsTree_itemClicked
00996 (
00997   QTreeWidgetItem * item,
00998   int column
00999 )
01000 {
01001   cmcDatabaseApi::cmcApplication * app;
01002   if( !(app = getApplication( item )) ) return;
01003 
01004 //  qDebug( "item clicked %d %s", item-> type(), qPrintable(item-> text(0)) );
01005 
01006   switch( item-> type() ) 
01007   {
01008     case twApplication:
01009     {
01010       break;
01011     }
01012 
01013     case twCategories:
01014     {
01015 
01016       propertyText-> clear();
01017       propertyText-> appendPlainText( app-> databaseName() + " -> Category Information" );
01018 
01019       propertyText-> appendPlainText
01020       (
01021          "     "
01022          "Category             "
01023          "Fields "
01024          "Conns  "
01025          "Total  "
01026          "Items  "
01027          "Forms  "
01028          "Views  "
01029          "Comment"
01030       );
01031 
01032       propertyText-> appendPlainText
01033       (
01034          "----+"
01035          "--------------------+"
01036          "------+"
01037          "------+"
01038          "------+"
01039          "------+"
01040          "------+"
01041          "------+"
01042          "---------------------------------------------"
01043       );
01044 
01045       for( int i = 0; i < app-> categoryDefs()-> count(); i++ )
01046       {
01047          cmcDatabaseApi::cmcCategoryDef * categoryDef = app-> categoryDef(i);
01048 
01049          QString catDef =
01050            QString("%1 %2 %3 %4 %5 %6 %7 %8")
01051            .arg(i,4)
01052            .arg(categoryDef-> categoryName(),-20)
01053            .arg(categoryDef-> fieldDefs()-> count(), 6)
01054            .arg(categoryDef-> connectionDefs()-> count(), 6)
01055            .arg(categoryDef-> fieldDefs()-> count() +
01056                 categoryDef-> connectionDefs()-> count(), 6)
01057            .arg(app-> cv()-> getItemCount( categoryDef-> categoryName() ),6)
01058            .arg(categoryDef-> formDefs()-> count(), 6)
01059            .arg(categoryDef-> viewDefs()-> count(), 6)
01060          ;
01061 
01062         propertyText-> appendPlainText( catDef );
01063 
01064       }
01065 
01066       propertyText-> appendPlainText
01067       (
01068          "----+"
01069          "--------------------+"
01070          "------+"
01071          "------+"
01072          "------+"
01073          "------+"
01074          "------+"
01075          "------+"
01076          "---------------------------------------------"
01077       );
01078 
01079       propertyText-> moveCursor( QTextCursor::Start );
01080 
01081       break;
01082     }
01083 
01084     case twCategory:
01085     {
01086       cmcDatabaseApi::cmcCategoryDef * categoryDef = app-> categoryDef( item-> text(0) );
01087 
01088       propertyText-> clear();
01089       propertyText-> appendPlainText( "Category...: " + categoryDef-> categoryName() );
01090 
01091       propertyText-> appendPlainText
01092       (
01093          "Comment....: " 
01094       );
01095 
01096       propertyText-> appendPlainText( QString("Fields.....: %1").arg(categoryDef-> fieldDefs()->      count()) );
01097       propertyText-> appendPlainText( QString("Connections: %1").arg(categoryDef-> connectionDefs()-> count()) );
01098       propertyText-> appendPlainText( QString("Total......: %1").arg(categoryDef-> fieldDefs()->      count() +
01099                                                                      categoryDef-> connectionDefs()-> count()) );
01100       propertyText-> appendPlainText( QString("Items......: %1").arg(app-> cv()-> getItemCount( categoryDef-> categoryName() )) );
01101       propertyText-> appendPlainText( QString("Forms......: %1").arg(categoryDef-> formDefs()->       count()) );
01102       propertyText-> appendPlainText( QString("Views......: %1").arg(categoryDef-> viewDefs()->       count()) );
01103 
01104       propertyText-> appendPlainText( "" );
01105       DumpCategoryFields( categoryDef );
01106       propertyText-> appendPlainText( "" );
01107       DumpCategoryConnections( categoryDef );
01108 
01109       propertyText-> moveCursor( QTextCursor::Start );
01110 
01111       break;
01112     }
01113   }
01114 }
01115 
01116 
01117 void winDumontEXE::on_applicationsTree_itemDoubleClicked
01118 (
01119   QTreeWidgetItem * item,
01120   int column
01121 )
01122 {
01123   cmcDatabaseApi::cmcApplication * app;
01124   if( !(app = getApplication( item )) ) return;
01125 
01126   switch( item-> type() ) 
01127   {
01128     /*
01129     ** If the form is open, then we want to put
01130     **  the form into a text editor.
01131     **
01132     */
01133     case twForm:
01134     {
01135       break;
01136     }
01137 
01138 
01139     /*
01140     ** If a view is clicked on, then we just want to 
01141     **  open the view in Commence.
01142     **
01143     */
01144     case twView:
01145     {
01146       app-> activate();
01147       app-> cv()-> showView( item-> text(0) );
01148 
01149       break;
01150     }
01151 
01152   }
01153 
01154 }
01155 
01156 
01157 void winDumontEXE::on_applicationsTree_customContextMenuRequested ( const QPoint & pos )
01158 {
01159   QTreeWidgetItem * item = applicationsTree-> currentItem();
01160 
01161   switch( item-> type() )
01162   {
01163     case twApplication:
01164     {
01165       QMenu * menu = new QMenu(this);
01166       menu-> addAction( actCheckOutAllScripts );
01167       menu-> popup( applicationsTree-> mapToGlobal(pos) );
01168       break;
01169     }
01170 
01171     case twForm:
01172     {
01173       QMenu * menu = new QMenu(this);
01174       menu-> addAction( actCheckOutFormScript );
01175       menu-> addAction( actCheckInFormScript );
01176       menu-> popup( applicationsTree-> mapToGlobal(pos) );
01177       break;
01178     }
01179 
01180     case twView:
01181     {
01182       QMenu * menu = new QMenu(this);
01183       menu-> addAction( actShowView );
01184       menu-> addAction( actDeleteView );
01185       menu-> popup( applicationsTree-> mapToGlobal(pos) );
01186       break;
01187     }
01188   }
01189 }
01190 
01191 void winDumontEXE::on_actCheckOutAllScripts_triggered ( bool checked )
01192 {
01193   QTreeWidgetItem * item = applicationsTree-> currentItem();
01194 
01195   cmcDatabaseApi::cmcApplication * app;
01196   if( !(app = getApplication( item )) ) return;
01197 
01198   switch( item-> type() )
01199   {
01200     case twApplication:
01201     {
01202       app-> checkOutAllFormScripts();
01203       break;
01204     }
01205   }
01206 
01207 }
01208 
01209 
01210 void winDumontEXE::on_actCheckOutFormScript_triggered( bool checked )
01211 {
01212   QTreeWidgetItem * item = applicationsTree-> currentItem();
01213 
01214   cmcDatabaseApi::cmcApplication * app;
01215   if( !(app = getApplication( item )) ) return;
01216 
01217   switch( item-> type() )
01218   {
01219     case twForm:
01220     {
01221       cmcDatabaseApi::cmcFormDef * formDef = 
01222         app-> categoryDef( getCategoryName(item) )-> formDef( item-> text(0) );
01223 
01224       if( !formDef ) return;
01225 
01226       formDef-> script()-> checkOut();
01227 
01228       break;
01229     }
01230   }
01231 
01232 }
01233 
01234 void winDumontEXE::on_actCheckInFormScript_triggered( bool checked )
01235 {
01236   QTreeWidgetItem * item = applicationsTree-> currentItem();
01237 
01238   cmcDatabaseApi::cmcApplication * app;
01239   if( !(app = getApplication( item )) ) return;
01240 
01241   switch( item-> type() )
01242   {
01243     case twForm:
01244     {
01245       cmcDatabaseApi::cmcFormDef * formDef = 
01246         app-> categoryDef( getCategoryName(item) )-> formDef( item-> text(0) );
01247 
01248       if( !formDef ) return;
01249 
01250       formDef-> script()-> checkIn();
01251 
01252       break;
01253     }
01254   }
01255 
01256 }
01257 
01258 void winDumontEXE::on_actShowView_triggered( bool checked )
01259 {
01260   QTreeWidgetItem * item = applicationsTree-> currentItem();
01261 
01262   cmcDatabaseApi::cmcApplication * app;
01263   if( !(app = getApplication( item )) ) return;
01264 
01265   switch( item-> type() )
01266   {
01267     case twView:
01268     {
01269       cmcDatabaseApi::cmcViewDef * viewDef = 
01270         app-> categoryDef( getCategoryName(item) )-> viewDef( item-> text(0) );
01271 
01272       if( !viewDef ) return;
01273 
01274       app-> activate();
01275       viewDef-> showView();
01276 
01277       break;
01278     }
01279   }
01280 
01281 }
01282 
01283 void winDumontEXE::on_actDeleteView_triggered( bool checked )
01284 {
01285   QTreeWidgetItem * item = applicationsTree-> currentItem();
01286 
01287   cmcDatabaseApi::cmcApplication * app;
01288   if( !(app = getApplication( item )) ) return;
01289 
01290   switch( item-> type() )
01291   {
01292     case twView:
01293     {
01294       cmcDatabaseApi::cmcViewDef * viewDef = 
01295         app-> categoryDef( getCategoryName(item) )-> viewDef( item-> text(0) );
01296 
01297       if( !viewDef ) return;
01298 
01299       if( QMessageBox::warning
01300       (
01301         this,
01302         "Delete: " + item-> text(0),
01303         "Are you sure you want to delete this view?",
01304         QMessageBox::Yes | QMessageBox::No
01305       ) == QMessageBox::Yes )
01306       {
01307         viewDef-> deleteView();
01308         delete item;
01309       }
01310 
01311       break;
01312     }
01313   }
01314 
01315 
01316 }
01317 
01318 
01319 
01320 
01321 
01322 
01323 
01324 
01325 
01326 
01327 #include "cmcExe.h"
01328 
01329 void winDumontEXE::on_actViewAppMonitor_triggered()
01330 {
01331   if( !m_cmcExe )
01332        m_cmcExe = new cmcExe(this);
01333 
01334   m_cmcExe-> show();
01335 }
01336 
01337 #include "QAxFactory.h"
01338 
01339 void winDumontEXE::timerEvent( QTimerEvent * event )
01340 {
01341   if( qApp-> arguments().contains("-embedding",Qt::CaseInsensitive) )
01342   {
01343     static int autoQuit = AUTO_QUIT;
01344     if( cmcObject::apps()-> children().count() == 0 &&
01345         QComObject::instanceCount()            == 0    )
01346     {
01347       if( !autoQuit-- )
01348       {
01349         qApp-> quit();
01350       }
01351       return;
01352     }
01353     autoQuit = AUTO_QUIT;
01354 
01355     cmcObject::apps()-> checkApps();
01356   }
01357 }
01358 
01359 /*
01360 ** This code prevents Dumont from being run twice.  It tries to find 
01361 **  a window with the same name (Dumont) and then if it finds it 
01362 **  it restores it.
01363 **
01364 */
01365 bool AlreadyRunning()
01366 {
01367   /*
01368   ** Find an existing window.  The variable .hwnd. is a
01369   **  handle-window.
01370   **
01371   */
01372   HWND hwnd = ::FindWindow( 0, TEXT(APP_NAME) );
01373 
01374   /*
01375   ** If a window was found
01376   **
01377   */
01378   if( ::IsWindow(hwnd) )
01379   {
01380     /*
01381     ** Get a popup if it was activated
01382     **
01383     */
01384     HWND hwndPopup = ::GetLastActivePopup(hwnd);
01385 
01386     /*
01387     ** Swap the popup if there was one
01388     **
01389     */
01390     if( ::IsWindow(hwndPopup) ) hwnd = hwndPopup;
01391 
01392     /*
01393     ** Bring the window (or the popup) to the foreground
01394     **
01395     */
01396     ::SetForegroundWindow(hwnd);
01397 
01398     /*
01399     ** If the window is iconified then bring it forward
01400     **
01401     */
01402     if( ::IsIconic(hwnd) ) ::ShowWindow( hwnd, SW_RESTORE );
01403 
01404     /*
01405     ** Return that we found a matching window.
01406     **
01407     */
01408     return( true );
01409 
01410   } // endif( ::IsWindow(hwnd) )
01411 
01412   return( false );
01413 
01414 } // endbool AlreadyRunning(void)
01415 
01416 
01417 bool winDumontEXE::checkError( QSettings & settings )
01418 {
01419   if( settings.status() )
01420   {
01421     QMessageBox::critical
01422     ( 
01423       this, 
01424       "Dumont.EXE", "Unable to set the registry\n"
01425       "Make sure you have administrator rights" 
01426     );
01427     return( true );
01428   }
01429 
01430   return( false );
01431 }
01432 
01433 
01434 void winDumontEXE::RegisterServer
01435 (
01436   const QUuid & clsid,
01437   const QString & progid,
01438   const QString & description,
01439   const QString & serverType,
01440   const QString & serverPath
01441 )
01442 {
01443   /*
01444   ** Check: HKEY_CLASSES_ROOT/Dumont.EXE for proper CLSID
01445   **
01446   */
01447   QSettings dexeSet( "HKEY_CLASSES_ROOT\\" + progid, QSettings::NativeFormat );
01448   if( dexeSet.value("CLSID/Default").toString() != clsid.toString() ||
01449       dexeSet.value("Default").toString()       != description        )
01450   {
01451     dexeSet.setValue("Default", description );             if( checkError(dexeSet) ) return;
01452     dexeSet.setValue( "CLSID/Default", clsid.toString() ); if( checkError(dexeSet) ) return;
01453   }
01454 
01455   /*
01456   ** Check: HKEY_CLASSES_ROOT/CLSID/{dumont-clsid}
01457   **
01458   */
01459   QSettings clsidSet( "HKEY_CLASSES_ROOT\\CLSID\\" + clsid.toString(), QSettings::NativeFormat );
01460   if( clsidSet.value( serverType + "/Default") != serverPath )
01461   {
01462     clsidSet.setValue("Default", description );              if( checkError(clsidSet) ) return;
01463     clsidSet.setValue(serverType + "/Default", serverPath ); if( checkError(clsidSet) ) return;
01464     clsidSet.setValue("ProgID/Default", progid );            if( checkError(clsidSet) ) return;
01465   }
01466 
01467 }
01468 
01469 
01470 int main(int argc, char **argv)
01471 {
01472   /*
01473   ** If Dumont is already running then we just shut down.
01474   **
01475   */
01476   if( AlreadyRunning() ) return( 0 );
01477 
01478   Q_INIT_RESOURCE(DumontEXE);
01479 
01480   /*
01481   ** Create the Qt application object.
01482   **
01483   */
01484   QApplication app(argc,argv);
01485 
01486   /*
01487   ** This allows a calling program to shutdown Dumont.  This is used
01488   **  to preload Dumont, for speed.  On some systems, because they are
01489   **  so slow to boot, when calling upon Dumont through COM or DCOM
01490   **  the call can time-out, causing unusual script errors.  By first
01491   **  loading Dumont from the command line, and allowing it to immediately
01492   **  shutdown, then Dumont essentially gets loaded into the windows
01493   **  cache, and when it's called upon later from a DCOM, it loads
01494   **  quicker.
01495   **
01496   */
01497   if( app.arguments().contains("/shutdown",Qt::CaseInsensitive) ||
01498       app.arguments().contains("-shutdown",Qt::CaseInsensitive)   )
01499   {
01500     exit(0);
01501   }
01502 
01503   /*
01504   ** We don't want the application to die when windows are closed.
01505   **
01506   */
01507   app.setQuitOnLastWindowClosed(false);
01508 
01509   /*
01510   ** Set the organization and application names for QSettings
01511   **  savage and restoration.
01512   **
01513   */
01514   app.setOrganizationDomain( ORG_DOMAIN );
01515   app.setApplicationName(    APP_NAME );
01516 
01517   /*
01518   ** Install the logger.
01519   **
01520   */
01521   qxtLoggerManager-> getLogger("dumont");
01522 
01523   /*
01524   ** Open the main window.
01525   **
01526   */
01527   winDumontEXE mainWindow;
01528 
01529   /*
01530   ** Register the server.
01531   **
01532   */
01533   if( app.arguments().contains("/register",Qt::CaseInsensitive) ||
01534       app.arguments().contains("-register",Qt::CaseInsensitive)   )
01535   {
01536     mainWindow.RegisterServer
01537     (
01538       "{C7860C20-9B6F-4f31-8293-31CB0C1799F0}",
01539       "Dumont.EXE",
01540       QString("Dumont.EXE Commence Application Extensions version ") + DUMONTEXE_VERSION,
01541       "LocalServer",
01542       qApp-> applicationFilePath()
01543     );
01544     exit(0);
01545   }
01546 
01547   /*
01548   ** Start the factory.  Do this after everything else gets started
01549   **  so that we can rest assured that everything that is suppose to
01550   **  exist does exist and we won't run in to bad pointer issues or
01551   **  issues with trying to acquire handles to objects that don't
01552   **  exist yet.
01553   **
01554   */
01555   DumontFactory dumontFactory;
01556 
01557 //  mainWindow.show();
01558 
01559   /*
01560   ** Run the application.
01561   **
01562   */
01563   int retVal = app.exec();
01564 
01565   /*
01566   ** Shutdown the COM interface.
01567   **
01568   */
01569   dumontFactory.stopServer();
01570 
01571   return( retVal );
01572 
01573 } // endint main(int argc, char **argv)
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties




~ ~ ~ ~ ~ ~
Source Code without Comments is like a Cranberry Garland
without the berries. Comment your Code!
 
Commence Database User Support Group Forum
http://newsgroup.showoff-db.org/
~ ~ ~ ~ ~ ~
Author: Mark Petryk
Lorimark Solutions, LLC
mark@lorimarksolutions.com