|
@@ -12887,6 +12887,7 @@ define a macro that returns the |Application| instance.
|
12887
|
12887
|
|
12888
|
12888
|
class NodeInserter;
|
12889
|
12889
|
class DeviceTreeModel;
|
|
12890
|
+class DatabaseNotification;
|
12890
|
12891
|
class Application : public QApplication@/
|
12891
|
12892
|
{@/
|
12892
|
12893
|
@[Q_OBJECT@]@;
|
|
@@ -12900,10 +12901,12 @@ class Application : public QApplication@/
|
12900
|
12901
|
Q_INVOKABLE bool login(const QString &user, const QString &password);
|
12901
|
12902
|
Q_INVOKABLE bool autoLogin();
|
12902
|
12903
|
QScriptEngine *engine;
|
12903
|
|
- QNetworkAccessManager *network;@/
|
|
12904
|
+ QNetworkAccessManager *network;
|
|
12905
|
+ DatabaseNotification *subscribe(const QString ¬ification);@/
|
12904
|
12906
|
@[public slots@]:@/
|
12905
|
12907
|
void setDatabaseConnected(bool status);
|
12906
|
12908
|
void setCurrentTypicaUser(const QString &user);
|
|
12909
|
+ void notify(const QString ¬ification);
|
12907
|
12910
|
@<Extended Application slots@>@;
|
12908
|
12911
|
@[signals@]:@/
|
12909
|
12912
|
void userChanged(const QString &user);
|
|
@@ -12912,6 +12915,8 @@ class Application : public QApplication@/
|
12912
|
12915
|
QDomDocument conf;
|
12913
|
12916
|
bool connectionStatus;
|
12914
|
12917
|
QString currentUser;
|
|
12918
|
+ QMap<QString, DatabaseNotification*> notifiers;
|
|
12919
|
+ QSqlDriver *notificationDriver;
|
12915
|
12920
|
};
|
12916
|
12921
|
|
12917
|
12922
|
@ The constructor for this class handles a few things that had previously been
|
|
@@ -12956,11 +12961,11 @@ if(app->load(QString("%1_%2").arg("Typica").arg(QLocale::system().name()), QStri
|
12956
|
12961
|
}
|
12957
|
12962
|
|
12958
|
12963
|
@ We also want to be able to access the application instance from within the
|
12959
|
|
-scripting engine. We don'@q'@>t need to be able to create new instances, just access
|
12960
|
|
-the one that already exists.
|
|
12964
|
+scripting engine. We don'@q'@>t need to be able to create new instances, just access the one that already exists.
|
12961
|
12965
|
|
12962
|
12966
|
@<Set up the scripting engine@>=
|
12963
|
12967
|
value = engine->newQObject(AppInstance);
|
|
12968
|
+value.setProperty("subscribe", engine->newFunction(Application_subscribe));
|
12964
|
12969
|
engine->globalObject().setProperty("Application", value);
|
12965
|
12970
|
|
12966
|
12971
|
@ The |configuration()| method provides access to an XML document containing the
|
|
@@ -13002,6 +13007,102 @@ bool Application::databaseConnected()
|
13002
|
13007
|
return connectionStatus;
|
13003
|
13008
|
}
|
13004
|
13009
|
|
|
13010
|
+@ Database notifications allow various parts of Typica to be aware when data in
|
|
13011
|
+the database may have been changed by another instance of Typica running on a
|
|
13012
|
+different computer or by another program that uses the same database. To pass
|
|
13013
|
+notifications to the various places that may be interested in these and not
|
|
13014
|
+bother notification aware controls that are uninterested in unrelated
|
|
13015
|
+notifications, a notification object is created for each notification.
|
|
13016
|
+
|
|
13017
|
+@<Application Implementation@>=
|
|
13018
|
+DatabaseNotification* Application::subscribe(const QString ¬ification)
|
|
13019
|
+{
|
|
13020
|
+ DatabaseNotification *retval;
|
|
13021
|
+ if(notifiers.contains(notification))
|
|
13022
|
+ {
|
|
13023
|
+ retval = notifiers.value(notification);
|
|
13024
|
+ }
|
|
13025
|
+ else
|
|
13026
|
+ {
|
|
13027
|
+ if(notifiers.size() == 0)
|
|
13028
|
+ {
|
|
13029
|
+ notificationDriver = QSqlDatabase::database().driver();
|
|
13030
|
+ connect(notificationDriver, SIGNAL(notification(QString)), this, SLOT(notify(QString)));
|
|
13031
|
+ }
|
|
13032
|
+ retval = new DatabaseNotification;
|
|
13033
|
+ connect(this, SIGNAL(aboutToQuit()), retval, SLOT(deleteLater()));
|
|
13034
|
+ if(notifiers.size() !=
|
|
13035
|
+ notificationDriver->subscribedToNotifications().size())
|
|
13036
|
+ {
|
|
13037
|
+ for(int i = 0; i < notifiers.size(); i++)
|
|
13038
|
+ {
|
|
13039
|
+ notificationDriver->subscribeToNotification(notifiers.keys().at(i));
|
|
13040
|
+ }
|
|
13041
|
+ }
|
|
13042
|
+ notifiers.insert(notification, retval);
|
|
13043
|
+ notificationDriver->subscribeToNotification(notification);
|
|
13044
|
+ }
|
|
13045
|
+ return retval;
|
|
13046
|
+}
|
|
13047
|
+
|
|
13048
|
+@ As the various parts of \pn{} operate mostly indepent of each other and
|
|
13049
|
+notifications from the current instance may not be immediately returned, it is
|
|
13050
|
+generally a good idea for operations that would generate a notification to also
|
|
13051
|
+signal that notification within the application.
|
|
13052
|
+
|
|
13053
|
+@<Application Implementation@>=
|
|
13054
|
+void Application::notify(const QString ¬ification)
|
|
13055
|
+{
|
|
13056
|
+ if(notifiers.contains(notification))
|
|
13057
|
+ {
|
|
13058
|
+ DatabaseNotification *notifier = notifiers.value(notification);
|
|
13059
|
+ notifier->forwardNotification(notification);
|
|
13060
|
+ }
|
|
13061
|
+}
|
|
13062
|
+
|
|
13063
|
+@ A function is provided to allow subscribing to notifications from scripts.
|
|
13064
|
+@<Function prototypes for scripting@>=
|
|
13065
|
+QScriptValue Application_subscribe(QScriptContext *context,
|
|
13066
|
+ QScriptEngine *engine);
|
|
13067
|
+
|
|
13068
|
+@ The implementation is trivial.
|
|
13069
|
+
|
|
13070
|
+@<Functions for scripting@>=
|
|
13071
|
+QScriptValue Application_subscribe(QScriptContext *context,
|
|
13072
|
+ QScriptEngine *engine)
|
|
13073
|
+{
|
|
13074
|
+ return engine->newQObject(
|
|
13075
|
+ AppInstance->subscribe(argument<QString>(0, context)));
|
|
13076
|
+}
|
|
13077
|
+
|
|
13078
|
+@ The DatabaseNotification object just needs a signal that interested objects
|
|
13079
|
+can connect to.
|
|
13080
|
+
|
|
13081
|
+@<Class declarations@>=
|
|
13082
|
+class DatabaseNotification : public QObject
|
|
13083
|
+{
|
|
13084
|
+ Q_OBJECT
|
|
13085
|
+ public:
|
|
13086
|
+ DatabaseNotification();
|
|
13087
|
+ public slots:
|
|
13088
|
+ void forwardNotification(const QString ¬ification);
|
|
13089
|
+ signals:
|
|
13090
|
+ void notify(const QString ¬ification);
|
|
13091
|
+};
|
|
13092
|
+
|
|
13093
|
+@ The implementation is trivial.
|
|
13094
|
+
|
|
13095
|
+@<Class declarations@>=
|
|
13096
|
+DatabaseNotification::DatabaseNotification() : QObject(NULL)
|
|
13097
|
+{
|
|
13098
|
+ /* Nothing needs to be done here. */
|
|
13099
|
+}
|
|
13100
|
+
|
|
13101
|
+void DatabaseNotification::forwardNotification(const QString ¬ification)
|
|
13102
|
+{
|
|
13103
|
+ emit notify(notification);
|
|
13104
|
+}
|
|
13105
|
+
|
13005
|
13106
|
@** Table editor for ordered arrays with SQL relations.
|
13006
|
13107
|
|
13007
|
13108
|
\noindent A database in use at Wilson's Coffee \char'046~Tea stores information
|