DumontEXE 0.0.1
cmcApplication.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 <QDateTime>
00026 #include <QDir>
00027 #include <QFile>
00028 #include <QMetaObject>
00029 #include <QMetaProperty>
00030 #include <QSettings>
00031 
00032 #include "cmcApplication.h"
00033 #include "cmcCategoryDefs.h"
00034 #include "cmcCategoryDef.h"
00035 #include "cmcFormDefs.h"
00036 #include "cmcFormDef.h"
00037 #include "cmcFormScript.h"
00038 #include "cmcVersion.h"
00039 #include "cmcCda.h"
00040 #include "cmcCdaItem.h"
00041 #include "cmcQueue.h"
00042 
00043 #include "cmcTreeModel.h"
00044 
00045 namespace cmcDatabaseApi {
00046 
00047 
00048 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00049 
00050 cmcApplication::cmcApplication( IDispatch * dispatch, const QString & dumontCategoryName, QObject * parent ):
00051   cmcApi( "", dispatch, this, parent )
00052 {
00053   /*
00054   ** Attempt to load the application extension definitions.
00055   **
00056   */
00057 //  if( !loadDefs() )
00058 //  {
00059 //    qDebug("defs not loaded");
00060 //  }
00061 
00062   /*
00063   ** Finally, set the object name equal to the application name so that
00064   **  it can be properly referenced in all our code areas.
00065   **
00066   */
00067   setObjectName( databaseName() );
00068 
00069   /*
00070   ** Remember the name of the dumont category.
00071   **
00072   */
00073   m_dumontCategoryName = dumontCategoryName;
00074 
00075 //  TRACE_FUNCTION
00076 
00077   /*!
00078   ** \note This routine makes reference to the \ref cmcObject::db() "db"
00079   **  object in the application.  What this seems to do is properly associate a
00080   **  reference count to the Application object - or Commence.
00081   **  In this condition, if the user closes Commence, and this cmcApplication
00082   **  object is still in existence somewhere in another application (namely the
00083   **  DumontROT or an external application) then the Commence application itself
00084   **  will not actually close, because there is an outstanding reference
00085   **  to its database object.  This is rather strange, because, technically
00086   **  we already have reference to its Application object, and given those
00087   **  facts, the application should already not shut down.  But, Commence
00088   **  doesn't work this way it seems.  Even incrementing (here) the AddRef()
00089   **  of the application object doesn't do the trick - to lock it into 
00090   **  memory.  However, if we simply make reference to the db object in Commence, 
00091   **  then, wholla, Commence is locked, until we delete that reference to the
00092   **  database object.  That doesn't seem right, but we are going to go with 
00093   **  it at this point, because, since we are using this reference to the Commence 
00094   **  application object in the DumontROT, we want to more or less permanently 
00095   **  lock it in memory, properly, the way it should be.  Once we delete this
00096   **  cmcApplication object, the CommenceDatabase object will be deleted 
00097   **  along with it, and the memory and pointers and reference counts will all
00098   **  be properly freed up.
00099   **
00100   ** \par
00101   ** Note that we reference the cv object rather than just the db object.  Note
00102   **  that there is no real fundamental differences between the two calls, except
00103   **  that calling cv causes the conversation to be registered, which also causes
00104   **  the db object to be registered as well.
00105   **
00106   */
00107   cv();
00108 
00109 } // endcmcApplication::cmcApplication( IDispatch * dispatch, QObject * parent ):
00110 
00111 
00112 cmcApplication::~cmcApplication()
00113 {
00114 //  TRACE_FUNCTION
00115 
00116   if( m_cda ) delete m_cda;
00117 
00118 }
00119 
00120 cmcCda * cmcApplication::cda()
00121 {
00122   if( !m_cda )
00123        m_cda = new cmcCda(this);
00124 
00125   return( m_cda );
00126 }
00127 
00128 cmcCdaItem * cmcApplication::cdaItem()
00129 {
00130   if( !m_cdaItem )
00131        m_cdaItem = cda()-> rootItem()-> childItem( QString("Application") );
00132 
00133   return( m_cdaItem );
00134 }
00135 
00136 QString cmcApplication::applicationName()
00137 {
00138 //  TRACE_FUNCTION
00139 
00140   return( aliasName()==""? databaseName():aliasName() );
00141 }
00142 
00143 long cmcApplication::currentScriptLevel( long i_level )
00144 {
00145 //  TRACE_FUNCTION
00146 
00147   if( i_level > -1 ) 
00148   {
00149     PutServerLong( "CurrentScriptLevel", i_level );
00150   }
00151 
00152   return( GetServerLong("CurrentScriptLevel") );
00153 }
00154 
00155 cmcDatabase * cmcApplication::database()
00156 {
00157 //  TRACE_FUNCTION
00158 
00159   /*
00160   ** Check the local reference to the database object.
00161   **  If we already have one then there's no need to fetch
00162   **  another.
00163   **
00164   */
00165   if( !m_database )
00166   {
00167     /*
00168     ** Try to get a dispatch interface to the database object.
00169     **
00170     */
00171     IDispatch * dispatch = GetServerObject( "database" );
00172 
00173     /*
00174     ** If we got a dispatch interface, then we can wrap it with our
00175     **  database object.
00176     **
00177     */
00178     if( dispatch )
00179     {
00180       /*
00181       ** Create a new CommenceDatabase object using this dispatch interface
00182       **  pointer.  Make sure it knows what application object created it.
00183       **
00184       */
00185       m_database = new cmcDatabase( dispatch, this );
00186 
00187       /*
00188       ** Remove one from the database reference because we added one in the
00189       ** invoke, and then added another in the newCommenceDatabase, so now
00190       ** that we're dont with the dispatch value, we can release it.
00191       **
00192       */
00193       dispatch-> Release();
00194     }
00195   }
00196 
00197   return( m_database );
00198 }
00199 
00200 QString cmcApplication::databaseDirectory()
00201 {
00202 //  TRACE_FUNCTION
00203 
00204   return( GetServerString("DatabaseDirectory") );
00205 }
00206 
00207 QString cmcApplication::databaseName()
00208 {
00209 //  TRACE_FUNCTION
00210 
00211   return( GetServerString("DatabaseName") );
00212 }
00213 
00214 long cmcApplication::defaultScriptLevel()
00215 {
00216 //  TRACE_FUNCTION
00217 
00218   return( GetServerLong("DefaultScriptLevel") );
00219 }
00220 
00221 QString cmcApplication::name()
00222 {
00223 //  TRACE_FUNCTION
00224 
00225   return( GetServerString("Name") );
00226 }
00227 
00228 QString cmcApplication::programDirectory()
00229 {
00230 //  TRACE_FUNCTION
00231 
00232   return( GetServerString("ProgramDirectory") );
00233 }
00234 
00235 QString cmcApplication::programName()
00236 {
00237 //  TRACE_FUNCTION
00238 
00239   return( GetServerString("ProgramName") );
00240 }
00241 
00242 QString cmcApplication::getVersion(void)
00243 {
00244 //  TRACE_FUNCTION
00245 
00246   return( version() );
00247 }
00248 
00249 QString cmcApplication::version()
00250 {
00251 //  TRACE_FUNCTION
00252 
00253   return( GetServerString("Version") );
00254 }
00255 
00256 bool cmcApplication::isScriptLevelSupported(void)
00257 {
00258 //  TRACE_FUNCTION
00259 
00260   return( false );
00261 }
00262 
00263 bool cmcApplication::sameDatabase()
00264 {
00265 //  TRACE_FUNCTION
00266 
00267   bool retVal = false;
00268   if( databaseName() == objectName() ) retVal = true;
00269   return( retVal );
00270 }
00271 
00272 cmcCategoryDefs * cmcApplication::categoryDefs()
00273 {
00274 //  TRACE_FUNCTION
00275 
00276   if(    !m_categoryDefs )
00277           m_categoryDefs = new cmcCategoryDefs(this);
00278   return( m_categoryDefs );
00279 }
00280 
00281 cmcCategoryDef * cmcApplication::categoryDef( const QString & categoryName )
00282 {
00283 //  TRACE_FUNCTION
00284 
00285   return( categoryDefs()-> get( categoryName ) );
00286 }
00287 
00288 cmcCategoryDef * cmcApplication::categoryDef( long index )
00289 {
00290   return( categoryDefs()-> get( index ) );
00291 }
00292 
00293 cmcStringList * cmcApplication::stringList( const QString & listName )
00294 {
00295   cmcStringList * retVal = findChild<cmcStringList*>(listName);
00296 
00297   if( !retVal )
00298   {
00299     retVal = new cmcStringList( listName, 0, this );
00300   }
00301 
00302   return( retVal );
00303 }
00304 
00305 
00306 cmcTreeModel * cmcApplication::applicationModel()
00307 {
00308 //  if( !m_appModel )
00309 //       m_appModel = new cmcTreeModel
00310 //       (
00311 //         this,
00312 //         "~cda",
00313 //         "id",
00314 //         "idParent",
00315 //         "itemName",
00316 //         "itemAttr",
00317 //         "itemData"
00318 //       );
00319 //
00320 //  return(m_appModel);
00321 
00322   return( NULL );
00323 
00324 }
00325 
00326 cmcQueue * cmcApplication::getQueue
00327 (
00328   const QString & queueName
00329 )
00330 {
00331   /*
00332   ** Find an existing queue by name
00333   **
00334   */
00335   cmcQueue * queue = findChild<cmcQueue*>(queueName);
00336 
00337   /*
00338   ** If a named queue could not be found then make
00339   **  a new one
00340   **
00341   */
00342   if( !queue )
00343        queue = new cmcQueue( queueName, app(), this );
00344 
00345   return( queue );
00346 
00347 }
00348 
00349 #define INI QSettings( iniFilename(), QSettings::IniFormat )
00350 
00351 QString cmcApplication::iniFilename()
00352 {
00353   return( databaseDirectory() + "\\data.ini" );
00354 }
00355 
00356 
00357 long cmcApplication::workgroupEnable()
00358 {
00359   return( INI.value( "Workgroup/Enable", -1 ).toInt() );
00360 }
00361 
00362 long cmcApplication::sharedDbId()
00363 {
00364   return( INI.value( "Workgroup/ShareDBId", -1 ).toInt() );
00365 }
00366 
00367 long cmcApplication::syncFiles()
00368 {
00369   return( INI.value( "Workgroup/SyncFiles", -1 ).toInt() );
00370 }
00371 
00372 long cmcApplication::shareDefault()
00373 {
00374   return( INI.value( "Workgroup/ShareDefault", -1 ).toInt() );
00375 }
00376 
00377 bool cmcApplication::isServer()
00378 {
00379   return( INI.value( "Workgroup/Server", false ).toBool() );
00380 }
00381 
00382 bool cmcApplication::isClient()
00383 {
00384   return( !INI.value( "Workgroup/Server", false ).toBool()  );
00385 }
00386 
00387 long cmcApplication::workgroupNumEntries()
00388 {
00389   return( INI.value( "Workgroup/NumEntries", -1 ).toInt() );
00390 }
00391 
00392 QString cmcApplication::backup( long index )
00393 {
00394   return( INI.value( QString("Workgroup/Backup%1").arg(index), "" ).toString() );
00395 }
00396 
00397 long cmcApplication::serverId()
00398 {
00399   return( INI.value( "Workgroup/ServerID", -1 ).toInt() );
00400 }
00401 
00402 long cmcApplication::syncValid()
00403 {
00404   return( INI.value( "Workgroup/SyncValid", -1 ).toInt() );
00405 }
00406 
00407 QString cmcApplication::title()
00408 {
00409   QString appName = "Commence";
00410 
00411   if( workgroupEnable() > 0 )
00412   {
00413     if( isServer() ) appName += "/SERVER";
00414     if( isClient() ) appName += "/CLIENT";
00415   }
00416 
00417   appName += " - " + databaseName();
00418 
00419   return( appName );
00420 }
00421 
00422 void cmcApplication::activate()
00423 {
00424   /*
00425   ** Find an existing window.  The variable .hwnd. is a
00426   **  handle-window.
00427   **
00428   */
00429   HWND hWnd = ::FindWindow( TEXT("Commence"), (const wchar_t *) (title().utf16()) );
00430 
00431   /*
00432   ** If a window was found
00433   **
00434   */
00435   if( ::IsWindow(hWnd) )
00436   {
00437     /*
00438     ** Get a popup if it was activated
00439     **
00440     */
00441     HWND hWndPopup = ::GetLastActivePopup(hWnd);
00442 
00443     /*
00444     ** Swap the popup if there was one
00445     **
00446     */
00447     if( ::IsWindow(hWndPopup) ) hWnd = hWndPopup;
00448 
00449     /*
00450     ** Bring the window (or the popup) to the foreground
00451     **
00452     */
00453     ::SetForegroundWindow(hWnd);
00454     ::SetActiveWindow(hWnd);
00455     ::ShowWindow(hWnd, SW_SHOW);
00456 
00457 //    ::SetWindowPos( hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE );
00458 
00459     /*
00460     ** If the window is iconified then bring it forward
00461     **
00462     */
00463     if( ::IsIconic(hWnd) ) ::ShowWindow( hWnd, SW_RESTORE );
00464 
00465   } // endif( ::IsWindow(hwnd) )
00466 
00467 //  qDebug( "activate done." );
00468 
00469 } // endvoid cmcApplication::activate()
00470 
00471 
00472 bool cmcApplication::checkOutAllFormScripts()
00473 {
00474   for( int i=0; i<categoryDefs()-> count(); i++ )
00475   {
00476     for( int j=0; j<categoryDef(i)-> formDefs()-> count(); j++ )
00477     {
00478       categoryDef(i)-> formDef(j)-> script()-> checkOut();
00479     }
00480   }
00481 
00482   return( true );
00483 
00484 }
00485 
00486 
00487 bool cmcApplication::updateCommonCode()
00488 {
00489   return( false );
00490 }
00491 
00492 
00493 } //endnamespace cmcDatabaseApi
00494 
 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