Tuesday, 10 August 2010

Detecting Application Idle in Qt 4

The Patient Management System we are writing required a timeout for logins after a certain period had elapsed. So we needed to detect application idle. A couple of examples exist on the the web, but seemed incomplete and not thread safe. I also wanted a singleton class model so that I could have notifications of idle in any of my QObjects. So here is my implementation. Comments and improvements will be appreciated.


Header File:


#ifndef IDLETIMER_H
#define IDLETIMER_H

#include
#include
#include
#include

class IdleTimer : public QObject
{
Q_OBJECT
public:
// Singleton class stuff
static IdleTimer* instance(QObject *parent=0, int seconds=0) {
static QMutex mutex;
if (!m_Instance) {
mutex.lock();
m_Instance = new IdleTimer(parent, seconds);
mutex.unlock();
}
return m_Instance;
}

static void drop() {
qDebug("IdleTimer dropped ...");
static QMutex mutex;
mutex.lock();

m_timer->stop();
if(m_timer) delete m_timer;

if (m_Instance)
delete m_Instance;
m_Instance = 0;
mutex.unlock();
}

void start(int seconds = 0);
void stop();

private:
explicit IdleTimer(QObject *parent, int seconds);
explicit IdleTimer() {}
~IdleTimer() {}

IdleTimer(const IdleTimer &); // hide copy constructor
IdleTimer& operator=(const IdleTimer &); // hide assign op

static IdleTimer *m_Instance;
static QTimer *m_timer;

static QMutex m_timeoutMutex;
static int m_timeout;

signals:
void idle();

private slots:
void idleTimeout();

protected:
bool eventFilter(QObject *obj, QEvent *ev);
};

#endif // IDLETIMER_H


And the implementation



/*!
* Small class for detecting idle in the applcation
*/

#include "IdleTimer.h"

// Static initialisers
IdleTimer *IdleTimer::m_Instance = 0;
QTimer *IdleTimer::m_timer = new QTimer();
int IdleTimer::m_timeout = 0;
QMutex IdleTimer::m_timeoutMutex;

/*!
* Class constructor
*/
IdleTimer::IdleTimer(QObject *parent, int seconds) :
QObject(parent)
{
m_timeoutMutex.lock();

if (seconds)
m_timeout = seconds;

Q_ASSERT(parent);
Q_ASSERT_X(m_timeout, "IdleTimer Constructor", "The timeout must be specified in the first call to instance.");

parent->installEventFilter(this);
m_timer->singleShot(m_timeout*1000, this, SLOT(idleTimeout()));

m_timeoutMutex.unlock();
}

/*!
* Either reset the timeout to a different value to restart the timer
*/
void IdleTimer::start(int seconds/*=0*/) {
m_timeoutMutex.lock();

if(seconds)
m_timeout = seconds;

Q_ASSERT_X(m_timeout, "IdleTimer reset", "A timeout must be specified either in this call or in the first call to instance.");

m_timer->start(m_timeout*1000);

m_timeoutMutex.unlock();
}

void IdleTimer::stop() {
m_timeoutMutex.lock();
m_timer->stop();
m_timeoutMutex.unlock();
}

/*!
* The vent filter
*/
bool IdleTimer::eventFilter(QObject *obj, QEvent *ev)
{
if(ev->type() == QEvent::KeyPress ||
ev->type() == QEvent::MouseMove)
// now reset your timer, for example
IdleTimer::m_timer->start();

// Must return to allow further processing
return QObject::eventFilter(obj, ev);
}

/*slot*/
void IdleTimer::idleTimeout() {
qDebug("Application has been idle, emitting idle signal ...");
emit idle();
}

Wednesday, 21 April 2010

Mounting virtualbox shares in a linux (Ubuntu) guest

Mounting VirtualBox shares in a Linux guest is not as straight forward as for a Windows guest. I have only tried this on a Ubuntu guest but I see no reason why it wouldn't work in other flavours.

Some pre-requisites:
  1. Make sure the VirtualBox guest additions have been installed. There are plenty of guides about this
  2. When you create your shared directories DO NOT accept the default name. Use a prefix. For example HostDocuments for the host Documents folders instead of Documents.
    The reason for this is if you use the default name a protocol error will be reported when you mount the shared dir. I don't know why but this small work around fixes the issue
  3. Make sure the vboxvfs module is loaded by adding vboxvfs to the end of /etc/modules

    sudo sh -c 'echo "vboxvfs" | cat >>/etc/modules'
Now we need to allow mounting of vbox shares by normal users.

  1. sudo select-editor and make sure nano is selected. This is a much nicer editor than vi
  2. Now edit the sudoer file using sudo visudo.

    Add the line: %plugdev ALL=(ALL)NOPASSWD:/sbin/mount.vboxsf
    It may be that the group plugdev is a Ubuntu only group. Choose a group that all users belong to. Or create a 'users' group and add the users to it
  3. Create a mounting script in /usr/local/bin.

    sudo nano /usr/local/bin/mountVboxShares

    Paste the following code, but replace the variables at the top and add sections as appropriate.

    #!/bin/bash

    PROJECTDIR="$HOME"/Projects
    PROJECTSHARE="HostProjects"

    DOCSDIR="$HOME"/Documents
    DOCSSHARE="HostDocuments"

    if [ ! -d "$PROJECTDIR" ]; then
    mkdir "$PROJECTDIR"
    fi
    /usr/bin/sudo mount.vboxsf -o uid=`id -r -u`,gid=`id -r -u` "$PROJECTSHARE" "$PROJECTDIR"

    if [ ! -d "$DOCSDIR" ]; then
    mkdir "$DOCSDIR"
    fi
    /usr/bin/sudo mount.vboxsf -o uid=`id -r -u`,gid=`id -r -u` "$DOCSSHARE" "$DOCSDIR"

  4. Allow everyone to execute this script sudo chmod 755 /usr/local/bin/mountVboxShares
  5. Finally add the mount script to the end of the system wide profile script sudo sh -c 'echo "/usr/local/bin/mountVboxShares" | cat >>/etc/profile'

Monday, 1 March 2010

Converting Joomla sites from 1.0 to 1.5 cheatsheet

Some useful links for Joomla 1.5 component development:


Monday, 8 February 2010

Ubutnu ext3 to ext4 upgrade - won't mount filesystem!

I have just had a little heart stop moment.

I followed the Ubuntu wiki instructions on migrating from ext3 to ext4. After the tune2fs bit I rebooted as instructed and the system could not mount the new filesystem. Errors about bad superblocks and bad group descriptors, but nothing being done about them. fsck did not run correctly and I was left with an un-mountable drive, so I could even mount as ext3. Ahhhh....

Fortunately I have a live CD install of 9.10 on USB from which I could boot and run a fsck.ext4 on my partition.

So my suggestion is that before migrating from ext3 to ext4 do two things:
  1. BACKUP all your data
  2. Do the migration from a live CD / USB. The advantage of this is that you save on all the reboots too.

Wednesday, 7 October 2009

Setting up qt4 with visual studio 2005 and 2008

It is not clear (or wasn't to me) how to use QT4 with Visual Studio. The key to the problem is that you need to re-compile QT4 for Visual Studio. If you are not using MingGW at all then you can do all this in the original QT directory. Otherwise copy the entire c:\qt\2009.03 directory to something like c:\qt\2009.03_vs2008

Open a VS command line prompt so that all the env vars are set up.

Run the configure script, my suggestion is:
C:\Qt\2009.03\qt>configure -no-qt3support -no-opengl -platform win32-msvc2005 -no-libtiff -no-dbus -no-phonon -no-phonon-backend -opensource -debug-and-release

Let it do it's thing

Then type nmake to build the VS libraries

Notes:
Use nmake confclean to clean the directory before running a new configure cmd

Tuesday, 29 September 2009

Setting up PostgresSQL on Ubuntu

Most of my database use has been with MySQL to date as I have LAMP installations for websites but I was looking for a DB to use with a new desktop application of ours. It seems that Postgres may be a better option. Below are the steps I needed to get a Postgres server running on my laptop.

1) Install the packages
# sudo apt-get install postgresql postgresql-client pgadmin3

This will install the latest versions, which for ubuntu 9.04 at this time is 8.3 if an older version installs then change the references to directories below as appropriate.

2) Change the admin passwords

# sudo -u postgres psql template1
This will start up the command line admin tool and select the template1 db which seems to be where postgre stores user credentials

# ALTER USER postgres WITH PASSWORD 'new password';
and quit by typing \q

3) Change the ubuntu postgres user password. This is a conveinence step as all the conf files are created with postgres user and group. You could add or edit them as root with sudo and then make sure they are all chown to postgres:postgres

# sudo passwd -d postgres
Will delete the current postgres password (needed otherwise you are asked for it in the next step)
# sudo su postgres -c passwd
Enter a new password. For simplicity use the same password as the admin user above, but can be anything so long as you remember it

Restart the server with
# sudo /etc/init.d/postgresql-8.3 restart

You can now use the pgAdmin tool to connect to the DB

Wednesday, 2 September 2009

Additions to the Surgical Tutorials

I have been making some additions to the Surgical Tutorials section of the website. Four topics added are:
The Airway and Ventilatory Management is part of a new ATLS notes section and hopefully the other tutorials will also provide for useful revision notes.

Sunday, 16 August 2009

EWTD 48 hour opt out survey

We have been running a short EWTD survey on the Surgeons Net site about the 48 hour EWTD week and opting out. If you haven't completed the survey then please contribute. But do note that ASiT and BOTA are going to be conducting a more detailed, longer survey in September.

If you are interested in the results then they are available live on line too.

Sunday, 25 January 2009

Target Google AdSense even more by rating your content

There is a nice article on AdSense published recently on DevShed. For my own note I had no idea you could direct what content you wanted Google to concentrate on for displaying relevant ads.

Put the main content inside these comment tags:

<!-- google_ad_section_start -->

<!-- google_ad_section_end -->

And things you want ignored inside:

<!-- google_ad_section_start(weight=ignore) -->

<!-- google_ad_section_end -->

Monday, 17 November 2008

Firefox 3 sesson restore

Not sure why but firefox seemed to lose it's session restore feature for me. Maybe something to do with having tab mix plus installed prior to the 2 -> 3 upgrade.

Anyhow here is how to restore session saving.

Enter about:config in the address bar and say yes to the behave yourself warning!

Search down for "browser.sessionstore.resume_session_once" and change the setting to true.

and restart ...

That's it.