33
44 This file is part of Charm, a task-based time tracking application.
55
6- Copyright (C) 2014-2017 Klarälvdalens Datakonsult AB, a KDAB Group company, [email protected] 6+ Copyright (C) 2014-2018 Klarälvdalens Datakonsult AB, a KDAB Group company, [email protected] 77
88 Author: Mirko Boehm <[email protected] > 99 Author: Frank Osterfeld <[email protected] > 3131#include " Core/CharmExceptions.h"
3232#include " Core/SqLiteStorage.h"
3333
34- #include " HttpClient/HttpJob.h"
3534#include " Idle/IdleDetector.h"
35+ #include " Lotsofcake/Configuration.h"
3636#include " Widgets/ConfigurationDialog.h"
3737#include " Widgets/NotificationPopup.h"
3838#include " Widgets/TasksView.h"
7070
7171namespace {
7272static const QByteArray StartTaskCommand = QByteArrayLiteral(" start-task: " );
73+ static const QByteArray RaiseWindowCommand = QByteArrayLiteral(" raise-window" );
7374}
7475
7576ApplicationCore *ApplicationCore::m_instance = nullptr ;
7677
77- ApplicationCore::ApplicationCore (TaskId startupTask, QObject *parent)
78+ ApplicationCore::ApplicationCore (TaskId startupTask, bool hideAtStart, QObject *parent)
7879 : QObject(parent)
7980 , m_actionStopAllTasks(this )
8081 , m_actionQuit(this )
@@ -95,6 +96,8 @@ ApplicationCore::ApplicationCore(TaskId startupTask, QObject *parent)
9596 &m_timeTracker, &m_tasksView, &m_eventView
9697}),
9798 m_startupTask(startupTask)
99+ , m_hideAtStart(hideAtStart)
100+
98101#ifdef Q_OS_WIN
99102 , m_windowsJumpList(new QWinJumpList(this ))
100103#endif
@@ -107,7 +110,7 @@ ApplicationCore::ApplicationCore(TaskId startupTask, QObject *parent)
107110 QCoreApplication::setOrganizationName (QStringLiteral (" KDAB" ));
108111 QCoreApplication::setOrganizationDomain (QStringLiteral (" kdab.com" ));
109112 QCoreApplication::setApplicationName (QStringLiteral (" Charm" ));
110- QCoreApplication::setApplicationVersion (QStringLiteral (CHARM_VERSION ));
113+ QCoreApplication::setApplicationVersion (CharmVersion ( ));
111114
112115 QLocalSocket uniqueApplicationSocket;
113116 QString serverName (QStringLiteral (" com.kdab.charm" ));
@@ -122,16 +125,20 @@ ApplicationCore::ApplicationCore(TaskId startupTask, QObject *parent)
122125#endif
123126 uniqueApplicationSocket.connectToServer (serverName, QIODevice::ReadWrite);
124127 if (uniqueApplicationSocket.waitForConnected (1000 )) {
128+ QByteArray command;
125129 if (startupTask != -1 ) {
126- QByteArray data (StartTaskCommand + QByteArray::number (startupTask) + ' \n ' );
127- qint64 written = uniqueApplicationSocket.write (data);
128- if (written == -1 || written != data.length ()) {
129- qWarning () << " Failed to pass " << data << " to running charm instance, error: "
130- << uniqueApplicationSocket.errorString ();
131- }
132- uniqueApplicationSocket.flush ();
133- uniqueApplicationSocket.waitForBytesWritten ();
130+ command = StartTaskCommand + QByteArray::number (startupTask);
131+ } else {
132+ command = RaiseWindowCommand;
134133 }
134+ command += ' \n ' ;
135+ qint64 written = uniqueApplicationSocket.write (command);
136+ if (written == -1 || written != command.length ()) {
137+ qWarning () << " Failed to pass " << command << " to running charm instance, error: "
138+ << uniqueApplicationSocket.errorString ();
139+ }
140+ uniqueApplicationSocket.flush ();
141+ uniqueApplicationSocket.waitForBytesWritten ();
135142 throw AlreadyRunningException ();
136143 }
137144
@@ -152,21 +159,24 @@ ApplicationCore::ApplicationCore(TaskId startupTask, QObject *parent)
152159 qRegisterMetaType<Event>(" Event" );
153160
154161 // exit process (app will only exit once controller says it is ready)
155- connect (&m_controller, SIGNAL ( readyToQuit ()), SLOT (
156- slotControllerReadyToQuit ()) );
162+ connect (&m_controller, &Controller:: readyToQuit,
163+ this , &ApplicationCore:: slotControllerReadyToQuit);
157164
158165 connectControllerAndModel (&m_controller, m_model.charmDataModel ());
159166 Charm::connectControllerAndView (&m_controller, &m_timeTracker);
160167
161168 // save the configuration (configuration is managed by the application)
162- connect (&m_timeTracker, SIGNAL (saveConfiguration ()),
163- SLOT (slotSaveConfiguration ()));
164- connect (&m_timeTracker, SIGNAL (showNotification (QString,QString)),
165- SLOT (slotShowNotification (QString,QString)));
169+ connect (&m_timeTracker, &CharmWindow::saveConfiguration,
170+ this , &ApplicationCore::slotSaveConfiguration);
171+ connect (&m_timeTracker, &TimeTrackingWindow::showNotification,
172+ this , &ApplicationCore::slotShowNotification);
173+ connect (&m_timeTracker, &TimeTrackingWindow::taskMenuChanged,
174+ this , &ApplicationCore::slotPopulateTrayIconMenu);
166175
167176 // save the configuration (configuration is managed by the application)
168- connect (&m_tasksView, SIGNAL (saveConfiguration ()),
169- SLOT (slotSaveConfiguration ()));
177+ connect (&m_tasksView, &TasksView::saveConfiguration,
178+ this , &ApplicationCore::slotSaveConfiguration);
179+ // due to multiple inheritence we can't use the new style connects here
170180 connect (&m_tasksView, SIGNAL (emitCommand (CharmCommand*)),
171181 &m_timeTracker, SLOT (sendCommand (CharmCommand*)));
172182 connect (&m_tasksView, SIGNAL (emitCommandRollback (CharmCommand*)),
@@ -177,18 +187,15 @@ ApplicationCore::ApplicationCore(TaskId startupTask, QObject *parent)
177187 &m_timeTracker, SLOT (sendCommandRollback (CharmCommand*)));
178188
179189 // my own signals:
180- connect (this , SIGNAL (goToState (State)), SLOT (setState (State)),
181- Qt::QueuedConnection);
182-
183- connect (&m_systrayContextMenu, &QMenu::aboutToShow, this ,
184- &ApplicationCore::slotStartTaskMenuAboutToShow);
190+ connect (this , &ApplicationCore::goToState,
191+ this , &ApplicationCore::setState, Qt::QueuedConnection);
185192
186193 // system tray icon:
187194 m_actionStopAllTasks.setText (tr (" Stop Current Task" ));
188195 m_actionStopAllTasks.setShortcut (Qt::Key_Escape);
189196 m_actionStopAllTasks.setShortcutContext (Qt::ApplicationShortcut);
190197 mainView ().addAction (&m_actionStopAllTasks); // for the shortcut to work
191- connect (&m_actionStopAllTasks, SIGNAL ( triggered ()), SLOT ( slotStopAllTasks ()) );
198+ connect (&m_actionStopAllTasks, &QAction:: triggered, this , &ApplicationCore:: slotStopAllTasks);
192199
193200 m_systrayContextMenu.addAction (&m_actionStopAllTasks);
194201 m_systrayContextMenu.addSeparator ();
@@ -207,65 +214,66 @@ ApplicationCore::ApplicationCore(TaskId startupTask, QObject *parent)
207214 m_actionQuit.setShortcut (Qt::CTRL + Qt::Key_Q);
208215 m_actionQuit.setText (tr (" Quit" ));
209216 m_actionQuit.setIcon (Data::quitCharmIcon ());
210- connect (&m_actionQuit, SIGNAL ( triggered ( bool )) ,
211- SLOT ( slotQuitApplication ()) );
217+ connect (&m_actionQuit, &QAction:: triggered,
218+ this , &ApplicationCore:: slotQuitApplication);
212219
213220 m_actionAboutDialog.setText (tr (" About Charm" ));
214- connect (&m_actionAboutDialog, SIGNAL ( triggered ()) ,
215- & mainView (), SLOT ( slotAboutDialog ()) );
221+ connect (&m_actionAboutDialog, &QAction:: triggered,
222+ &m_timeTracker, &TimeTrackingWindow:: slotAboutDialog);
216223
217224 m_actionPreferences.setText (tr (" Preferences" ));
218225 m_actionPreferences.setIcon (Data::configureIcon ());
219- connect (&m_actionPreferences, SIGNAL ( triggered ( bool )) ,
220- &mainView (), SLOT ( slotEditPreferences ( bool )) );
226+ connect (&m_actionPreferences, &QAction:: triggered,
227+ &m_timeTracker, &TimeTrackingWindow:: slotEditPreferences);
221228 m_actionPreferences.setEnabled (true );
222229
223230 m_actionImportFromXml.setText (tr (" Import Database from Previous Export..." ));
224- connect (&m_actionImportFromXml, SIGNAL ( triggered ()) ,
225- &mainView (), SLOT ( slotImportFromXml ()) );
231+ connect (&m_actionImportFromXml, &QAction:: triggered,
232+ &m_timeTracker, &TimeTrackingWindow:: slotImportFromXml);
226233 m_actionExportToXml.setText (tr (" Export Database..." ));
227- connect (&m_actionExportToXml, SIGNAL ( triggered ()) ,
228- &mainView (), SLOT ( slotExportToXml ()) );
234+ connect (&m_actionExportToXml, &QAction:: triggered,
235+ &m_timeTracker, &TimeTrackingWindow:: slotExportToXml);
229236 m_actionSyncTasks.setText (tr (" Update Task Definitions..." ));
230- connect (&m_actionSyncTasks, SIGNAL (triggered ()),
231- &mainView (), SLOT (slotSyncTasks ()));
237+ // the signature of QAction::triggered does not match slotSyncTasks
238+ connect (&m_actionSyncTasks,&QAction::triggered,
239+ &m_timeTracker, &TimeTrackingWindow::slotSyncTasksVerbose);
232240 m_actionImportTasks.setText (tr (" Import and Merge Task Definitions..." ));
233- connect (&m_actionImportTasks, SIGNAL ( triggered ()) ,
234- &mainView (), SLOT ( slotImportTasks ()) );
241+ connect (&m_actionImportTasks, &QAction:: triggered,
242+ &m_timeTracker, &TimeTrackingWindow:: slotImportTasks);
235243 m_actionExportTasks.setText (tr (" Export Task Definitions..." ));
236- connect (&m_actionExportTasks, SIGNAL ( triggered ()) ,
237- &mainView (), SLOT ( slotExportTasks ()) );
244+ connect (&m_actionExportTasks, &QAction:: triggered,
245+ &m_timeTracker, &TimeTrackingWindow:: slotExportTasks);
238246 m_actionCheckForUpdates.setText (tr (" Check for Updates..." ));
239247#if 0
240248 // TODO this role should be set to have the action in the app menu, but that
241249 // leads to duplicated entries, as each of the three main windows adds the action to the menu
242250 // and Qt doesn't prevent duplicates (#222)
243251 m_actionCheckForUpdates.setMenuRole(QAction::ApplicationSpecificRole);
244252#endif
245- connect (&m_actionCheckForUpdates, SIGNAL ( triggered ()) ,
246- &mainView (), SLOT ( slotCheckForUpdatesManual ()) );
253+ connect (&m_actionCheckForUpdates, &QAction:: triggered,
254+ &m_timeTracker, &TimeTrackingWindow:: slotCheckForUpdatesManual);
247255 m_actionEnterVacation.setText (tr (" Enter Vacation..." ));
248- connect (&m_actionEnterVacation, SIGNAL ( triggered ()) ,
249- &mainView (), SLOT ( slotEnterVacation ()) );
256+ connect (&m_actionEnterVacation, &QAction:: triggered,
257+ &m_timeTracker, &TimeTrackingWindow:: slotEnterVacation);
250258 m_actionActivityReport.setText (tr (" Activity Report..." ));
251259 m_actionActivityReport.setShortcut (Qt::CTRL + Qt::Key_A);
252- connect (&m_actionActivityReport, SIGNAL ( triggered ()) ,
253- &mainView (), SLOT ( slotActivityReport ()) );
260+ connect (&m_actionActivityReport, &QAction:: triggered,
261+ &m_timeTracker, &TimeTrackingWindow:: slotActivityReport);
254262 m_actionWeeklyTimesheetReport.setText (tr (" Weekly Timesheet..." ));
255263 m_actionWeeklyTimesheetReport.setShortcut (Qt::CTRL + Qt::Key_R);
256- connect (&m_actionWeeklyTimesheetReport, SIGNAL ( triggered ()) ,
257- &mainView (), SLOT ( slotWeeklyTimesheetReport ()) );
264+ connect (&m_actionWeeklyTimesheetReport, &QAction:: triggered,
265+ &m_timeTracker, &TimeTrackingWindow:: slotWeeklyTimesheetReport);
258266 m_actionMonthlyTimesheetReport.setText (tr (" Monthly Timesheet..." ));
259267 m_actionMonthlyTimesheetReport.setShortcut (Qt::CTRL + Qt::Key_M);
260- connect (&m_actionMonthlyTimesheetReport, SIGNAL ( triggered ()) ,
261- &mainView (), SLOT ( slotMonthlyTimesheetReport ()) );
268+ connect (&m_actionMonthlyTimesheetReport, &QAction:: triggered,
269+ &m_timeTracker, &TimeTrackingWindow:: slotMonthlyTimesheetReport);
262270
263271 // set up idle detection
264272 m_idleDetector = IdleDetector::createIdleDetector (this );
265273 Q_ASSERT (m_idleDetector);
266274 connect (m_idleDetector, SIGNAL (maybeIdle ()), SLOT (slotMaybeIdle ()));
267275
268- setHttpActionsVisible (HttpJob::credentialsAvailable ());
276+ setHttpActionsVisible (Lotsofcake::Configuration (). isConfigured ());
269277 // add default plugin path for deployment
270278 QCoreApplication::addLibraryPath (QCoreApplication::applicationDirPath ()
271279 + QStringLiteral (" /plugins" ));
@@ -289,7 +297,7 @@ ApplicationCore::~ApplicationCore()
289297 m_instance = nullptr ;
290298}
291299
292- void ApplicationCore::slotStartTaskMenuAboutToShow ()
300+ void ApplicationCore::slotPopulateTrayIconMenu ()
293301{
294302 const auto newActions = m_timeTracker.menu ()->actions ();
295303 if (m_taskActions == newActions)
@@ -307,15 +315,17 @@ void ApplicationCore::slotHandleUniqueApplicationConnection()
307315 if (!socket->canReadLine ())
308316 return ;
309317 while (socket->canReadLine ()) {
310- QByteArray data = socket->readLine ().trimmed ();
318+ const QByteArray data = socket->readLine ().trimmed ();
311319 if (data.startsWith (StartTaskCommand)) {
312320 bool ok = true ;
313- TaskId id = data.mid (StartTaskCommand.length ()).toInt (&ok);
321+ const TaskId id = data.mid (StartTaskCommand.length ()).toInt (&ok);
314322 if (ok) {
315323 m_timeTracker.slotStartEvent (id);
316324 } else {
317325 qWarning () << " Received invalid argument:" << data;
318326 }
327+ } else if (data.startsWith (RaiseWindowCommand)) {
328+ // nothing to do, see below
319329 }
320330 }
321331 socket->deleteLater ();
@@ -326,8 +336,10 @@ void ApplicationCore::slotHandleUniqueApplicationConnection()
326336void ApplicationCore::showMainWindow (ShowMode mode)
327337{
328338 m_timeTracker.show ();
339+ m_timeTracker.setWindowState (m_timeTracker.windowState () & ~Qt::WindowMinimized);
329340 if (mode == ShowMode::ShowAndRaise) {
330341 m_timeTracker.raise ();
342+ m_timeTracker.activateWindow ();
331343#ifdef Q_OS_WIN
332344 // krazy:cond=captruefalse,null
333345 int idActive = GetWindowThreadProcessId (GetForegroundWindow (), NULL );
@@ -376,7 +388,7 @@ void ApplicationCore::createFileMenu(QMenuBar *menuBar)
376388 menu->addAction (&m_actionExportTasks);
377389
378390#ifdef Q_OS_OSX
379- if (!QString::fromLatin1 (UPDATE_CHECK_URL ).isEmpty ()) {
391+ if (!CharmUpdateCheckUrl ( ).isEmpty ()) {
380392 menu->addSeparator ();
381393 menu->addAction (&m_actionCheckForUpdates);
382394 }
@@ -394,7 +406,7 @@ void ApplicationCore::createHelpMenu(QMenuBar *menuBar)
394406 menu->setTitle (tr (" Help" ));
395407 menu->addAction (&m_actionAboutDialog);
396408#ifdef Q_OS_WIN
397- if (!QString::fromLatin1 (UPDATE_CHECK_URL ).isEmpty ())
409+ if (!CharmUpdateCheckUrl ( ).isEmpty ())
398410 menu->addAction (&m_actionCheckForUpdates);
399411
400412#endif
@@ -403,6 +415,7 @@ void ApplicationCore::createHelpMenu(QMenuBar *menuBar)
403415
404416CharmWindow &ApplicationCore::mainView ()
405417{
418+ m_timeTracker.setHideAtStartup (m_hideAtStart);
406419 return m_timeTracker;
407420}
408421
@@ -857,14 +870,10 @@ void ApplicationCore::slotShowNotification(const QString &title, const QString &
857870
858871void ApplicationCore::slotShowTasksEditor ()
859872{
860- m_tasksView.show ();
861- m_tasksView.raise ();
862- m_tasksView.activateWindow ();
873+ CharmWindow::showView (&m_tasksView);
863874}
864875
865876void ApplicationCore::slotShowEventEditor ()
866877{
867- m_eventView.show ();
868- m_eventView.raise ();
869- m_eventView.activateWindow ();
878+ CharmWindow::showView (&m_eventView);
870879}
0 commit comments