forked from qt-creator/qt-creator
		
	
		
			
	
	
		
			538 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			538 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | /*! | ||
|  | \page mode.html | ||
|  | \title 13. Adding a mode | ||
|  | 
 | ||
|  | When we are working in Qt Creator then we in one of the six modes below. | ||
|  | 
 | ||
|  | \list | ||
|  | \o Welcome | ||
|  | \o Edit | ||
|  | \o Debug | ||
|  | \o Project | ||
|  | \o Help | ||
|  | \o Output | ||
|  | \endlist | ||
|  | 
 | ||
|  | By selecting different modes in Qt creator we can quickly switch between different task spaces, such | ||
|  | as editing, browsing the Qt Creator manual, setting up the build environment, etc. | ||
|  | Different modes can be selected either by clicking on the mode selectors or through keyboard shortcuts. | ||
|  | 
 | ||
|  | The following figure shows the mode selectors in the Qt Creator. | ||
|  | 
 | ||
|  | \inlineimage qtc-modes-13.png  | ||
|  | 
 | ||
|  | 
 | ||
|  | Now in this chapter we are concerned about learning to add a new mode and a "LoggerMode" mode selector will be availble in Qt Creator. | ||
|  | 
 | ||
|  | \section1 13.1 Core Classes and Interfaces | ||
|  | 
 | ||
|  | To support a new mode we need to  | ||
|  | \list | ||
|  | \o Implement a plugin \bold {(ExtensionSystem::IPlugin } implementation) class that exposes the new mode.Chapter 2 in this  | ||
|  |    document provides a detailed description on creating plugins by implementing the ExtensionSystem::IPlugin interface. | ||
|  | \o Implement the \bold{(Core::IMode)} interface. This interface allows us to add a new mode in Qt creator | ||
|  | \endlist | ||
|  | 
 | ||
|  | 
 | ||
|  | \section2 Step 1. Core::IMode interface | ||
|  | This interface abstracts the creation of a mode, adding an icon to the mode selector, setting the mode priority, | ||
|  | setting a unique made name. The \bold {Core::IMode} interface is declared as follows in scr/plugins/coreplugin/imode.h | ||
|  | \code | ||
|  | namespace Core { | ||
|  | 
 | ||
|  |     class CORE_EXPORT IMode : public IContext | ||
|  |     { | ||
|  |         Q_OBJECT | ||
|  | 
 | ||
|  |     public: | ||
|  |         IMode(QObject *parent = 0) : IContext(parent) {} | ||
|  |         virtual ~IMode() {} | ||
|  | 
 | ||
|  |         virtual QString name() const = 0; | ||
|  |         virtual QIcon icon() const = 0; | ||
|  |         virtual int priority() const = 0; | ||
|  |         virtual const char *uniqueModeName() const = 0; | ||
|  |     }; | ||
|  | } // namespace Core | ||
|  | \endcode | ||
|  | 
 | ||
|  | Notice that Core::IMode inherits Core::IContext. Core::IContext is an interface through which | ||
|  | Qt Creator picks up the widget corresponding to the mode. The Core::IContext interface is declared  | ||
|  | as follows. | ||
|  | 
 | ||
|  | \code | ||
|  | namespace Core  | ||
|  | { | ||
|  | 
 | ||
|  |     class CORE_EXPORT IContext : public QObject | ||
|  |     { | ||
|  |         Q_OBJECT | ||
|  | 
 | ||
|  |     public: | ||
|  |         IContext(QObject *parent = 0) : QObject(parent) {} | ||
|  |         virtual ~IContext() {} | ||
|  | 
 | ||
|  |         virtual QList<int> context() const = 0; | ||
|  |         virtual QWidget *widget() = 0; | ||
|  |         virtual QString contextHelpId() const { return QString(); } | ||
|  |     }; | ||
|  | } | ||
|  | \endcode | ||
|  | 
 | ||
|  | \section1 13.2 Adding a new mode | ||
|  | Lets add a mode to Qt Creator called "LoggerMode". LoggerMode allows the user (developer) to log the number of hours he/she | ||
|  | has worked on a project. The following steps explain how the new mode "LoggerMode" is added. | ||
|  | 
 | ||
|  | \section2 Step 1. Declaring the LoggerMode class | ||
|  | We first begin by declaring a class called LoggerMode that implements the Core::IMode interface. | ||
|  | The class definition is as follows. | ||
|  | \code | ||
|  | #include <coreplugin/imode.h> | ||
|  | 
 | ||
|  | struct LoggerModeData; | ||
|  | class LoggerMode : public Core::IMode | ||
|  | { | ||
|  |     Q_OBJECT | ||
|  | 
 | ||
|  | public: | ||
|  |     LoggerMode(); | ||
|  |     ~LoggerMode(); | ||
|  | 
 | ||
|  |     QString name() const; | ||
|  |     QIcon icon() const; | ||
|  |     int priority() const; | ||
|  |     QWidget *widget(); | ||
|  |     const char *uniqueModeName() const; | ||
|  |     QList<int> context() const; | ||
|  |     void activated(); | ||
|  |     QString contextHelpId() const { return QLatin1String("Qt Creator"); } | ||
|  | 
 | ||
|  | private: | ||
|  |     LoggerModeData *d; | ||
|  | }; | ||
|  | \endcode | ||
|  | 
 | ||
|  | \section2 Step 2. Implementing the LoggerMode class | ||
|  | Declaring the private variables of the LoggerMode class. | ||
|  | \code | ||
|  | struct LoggerModeData | ||
|  | { | ||
|  |     QWidget *m_widget; | ||
|  | }; | ||
|  | \endcode | ||
|  | The constructor creates a new blank widget just for now to get started with the mode.  | ||
|  | The constructor and the destructor are implemented as follows | ||
|  | \code | ||
|  | LoggerMode::LoggerMode() | ||
|  | { | ||
|  |     d = new LoggerModeData; | ||
|  |     d->m_widget = new QWidget; | ||
|  | } | ||
|  | 
 | ||
|  | LoggerMode::~LoggerMode() | ||
|  | { | ||
|  |     delete d->m_widget; | ||
|  |     delete d; | ||
|  | } | ||
|  | \endcode | ||
|  | The \bold {name()} method returns a name for the new mode selector. | ||
|  | \code | ||
|  | QString LoggerMode::name() const | ||
|  | { | ||
|  |     return tr("LoggerMode"); | ||
|  | } | ||
|  | \endcode | ||
|  | 
 | ||
|  | The \bold {icon()} method  returns a logo for the new mode selector. | ||
|  | \code | ||
|  | QIcon LoggerMode::icon() const | ||
|  | { | ||
|  |     return QIcon(QLatin1String(":/core/images/qtcreator_logo_32.png")); | ||
|  | } | ||
|  | \endcode | ||
|  | 
 | ||
|  | The \bold {priority()} method is implemented to return a priority for the mode. Modes of higher | ||
|  | priority are shown above modes of lower priority. The highest priority in Qt Creator is currently | ||
|  | 100 and is associated with the Welcome mode. We return 0 from LoggerMode, becasue we want this | ||
|  | mode to appear at the end. | ||
|  | \code | ||
|  | int LoggerMode::priority() const | ||
|  | { | ||
|  |     return 0; | ||
|  | } | ||
|  | \endcode | ||
|  | Thw \bold {widget()} method returns a widget to the new mode. | ||
|  | \code | ||
|  | QWidget* LoggerMode::widget() | ||
|  | { | ||
|  |     return d->m_widget; | ||
|  | } | ||
|  | \endcode | ||
|  | 
 | ||
|  | The \bold {uniqueModeName()} returns the name of the mode to the "LoggerMode" Class. | ||
|  | \code | ||
|  | const char* LoggerMode::uniqueModeName() const | ||
|  | { | ||
|  |     return "LoggerMode" ; | ||
|  | } | ||
|  | \endcode | ||
|  | The \bold {context()} method returns an empty list of integers to tne "LoggerMode" class. | ||
|  | \code | ||
|  | QList<int> LoggerMode::context() const | ||
|  | { | ||
|  |     return QList<int>(); | ||
|  | } | ||
|  | \endcode | ||
|  | 
 | ||
|  | \section2 Step 3. Implementing the "LoggerMode" plugin | ||
|  | We implement the "LoggerMode" plugin very similar to the DoNothingPlugin  class described in Chapter 2.  | ||
|  | Here we only look at the implementation of the initialize() method. | ||
|  | \code | ||
|  | bool LoggerModePlugin::initialize(const QStringList& args, QString *errMsg) | ||
|  | { | ||
|  |     Q_UNUSED(args); | ||
|  |     Q_UNUSED(errMsg); | ||
|  | 
 | ||
|  |     loggerMode = new LoggerMode; | ||
|  |     addAutoReleasedObject(loggerMode); | ||
|  | 
 | ||
|  |     return true; | ||
|  | } | ||
|  | \endcode | ||
|  | \section2 Step 4. Testing the plugin. | ||
|  | Upon compiling the plugin and restarting Qt Creator, we can notice the "LoggerMode" mode selector in the Qt creator. | ||
|  | 
 | ||
|  | \inlineimage qtc-loggermode-13.png  | ||
|  | 
 | ||
|  | \section1 13.3 Adding Functionality to the "LoggerMode" | ||
|  | The actual function of the "LoggerMode" is to log data in a text file about a project, such as progress , hours worked, | ||
|  | description etc. | ||
|  | 
 | ||
|  | \section2 Step 1. Modifying the "LoggerMode" Class  | ||
|  | 
 | ||
|  | To add the functionalities, the LoggerMode class is further modified. | ||
|  | The code block is given as follows. | ||
|  | 
 | ||
|  | \code | ||
|  | struct LoggerModeData; | ||
|  | class LoggerMode :public Core::IMode | ||
|  | { | ||
|  |     Q_OBJECT | ||
|  | 
 | ||
|  | public: | ||
|  |     LoggerMode(); | ||
|  |     ~LoggerMode(); | ||
|  |      ... | ||
|  |      ... | ||
|  | 
 | ||
|  | protected slots: | ||
|  |     void addNewStackWidgetPage(const QString projectName); | ||
|  |     void addItem(); | ||
|  | 
 | ||
|  | private: | ||
|  |     ... | ||
|  | }; | ||
|  | \endcode | ||
|  | 
 | ||
|  | The constructor of the \bold {LoggerMode} class is modified as follows. | ||
|  | \code | ||
|  | LoggerMode::LoggerMode() | ||
|  | { | ||
|  |     d = new LoggerModeData; | ||
|  |     d->m_widget = new QWidget; | ||
|  | 
 | ||
|  |     //Current Projects Label and combobox widget are created. | ||
|  | 
 | ||
|  |     d->currentProjectsLabel = new QLabel("Current projects :"); | ||
|  |     d->currentProjectsLabel->setFixedWidth(90); | ||
|  |     d->currentProjectsCombobox = new QComboBox; | ||
|  |     d->currentProjectsCombobox->setSizePolicy(QSizePolicy::Preferred, | ||
|  |                                           QSizePolicy::Preferred); | ||
|  | 
 | ||
|  |     //Add Projects Label and combobox widget are created. | ||
|  | 
 | ||
|  |     d->addProjectLabel = new QLabel("Add Project :"); | ||
|  |     d->addProjectLabel->setAlignment(Qt::AlignRight); | ||
|  |     d->addProjectComboBox = new QComboBox; | ||
|  |     d->addProjectComboBox->setSizePolicy(QSizePolicy::Preferred, | ||
|  |                                      QSizePolicy::Preferred); | ||
|  |     d->addProjectComboBox->setEditable(true); | ||
|  | 
 | ||
|  |     d->addToProjectButton = new QPushButton(tr("Add Project")); | ||
|  |     d->addToProjectButton->setFixedWidth(80); | ||
|  | 
 | ||
|  |     //Creating a horizontal Layout | ||
|  | 
 | ||
|  |     QHBoxLayout *hLayout = new QHBoxLayout; | ||
|  |     hLayout->addWidget(d->currentProjectsLabel); | ||
|  |     hLayout->addWidget(d->currentProjectsCombobox); | ||
|  |     hLayout->addWidget(d->addProjectLabel); | ||
|  |     hLayout->addWidget(d->addProjectComboBox); | ||
|  |     hLayout->addWidget(d->addToProjectButton); | ||
|  | 
 | ||
|  |     //creating a stackedWidget | ||
|  | 
 | ||
|  |     d->stackedWidget = new QStackedWidget; | ||
|  | 
 | ||
|  |     //creating a vertical layout | ||
|  | 
 | ||
|  |     QVBoxLayout* layout = new QVBoxLayout; | ||
|  |     layout->addLayout(hLayout); | ||
|  |     layout->addWidget(d->stackedWidget); | ||
|  | 
 | ||
|  |     d->m_widget->setLayout(layout); | ||
|  | 
 | ||
|  |     d->addProjectComboBox->addItem("Project 1"); | ||
|  |     d->addProjectComboBox->addItem("Project 2"); | ||
|  |     d->addProjectComboBox->addItem("Project 3"); | ||
|  | 
 | ||
|  |     connect(d->addToProjectButton,SIGNAL(clicked()), | ||
|  |             this,SLOT(addItem())); | ||
|  | 
 | ||
|  |     connect(d->currentProjectsCombobox, SIGNAL(currentIndexChanged(int)), | ||
|  |             d->stackedWidget, SLOT(setCurrentIndex(int))); | ||
|  | } | ||
|  | 
 | ||
|  | \endcode | ||
|  | 
 | ||
|  | Implementation of the \bold{addNewStackWidgetPage()} slot of \bold {LoggerMode} class | ||
|  | \code | ||
|  | void LoggerMode::addNewStackWidgetPage(const QString projectName) | ||
|  | { | ||
|  |     d->stackedWidget->addWidget(new LoggerModeWidget(projectName)); | ||
|  | }  | ||
|  | \endcode | ||
|  | 
 | ||
|  | Implementation of the \bold{addItem()} slot of \bold {LoggerMode} class | ||
|  | \code | ||
|  | void LoggerMode::addItem() | ||
|  | { | ||
|  |     d->currentProjectsCombobox->addItem(d->addProjectComboBox->currentText()); | ||
|  |     addNewStackWidgetPage(d->currentProjectsCombobox->itemText(0)); | ||
|  | } | ||
|  | \endcode | ||
|  | 
 | ||
|  | The effect of the above block of code  can be seen in the following image. | ||
|  | 
 | ||
|  | \inlineimage  qtc-loggerpage-13.png | ||
|  | 
 | ||
|  | 
 | ||
|  | \section2 Step 2. Declaration of the "LoggerModeWidget" class | ||
|  | Reffering to the above image, when ever we select a project from  the \bold {Add Project} combobox and click | ||
|  | \bold {Add Project} button a new project is added to the \bold {Current projects} list and and a corresponding | ||
|  | \bold {LoggerModeWidget} is opened, for logging different informations about the project. | ||
|  | The declaration of the \bold {LoggerModeWidget} class is shown in the following code block. | ||
|  | 
 | ||
|  |  \code | ||
|  | #include <QWidget> | ||
|  | 
 | ||
|  | struct LoggerModeWidgetData; | ||
|  | class LoggerModeWidget : public QWidget | ||
|  | { | ||
|  |     Q_OBJECT | ||
|  | 
 | ||
|  | public: | ||
|  |     LoggerModeWidget(const QString projectName, QWidget* parent = 0); | ||
|  |     ~LoggerModeWidget(); | ||
|  | 
 | ||
|  | public slots: | ||
|  |     void setProjectName(QString name); | ||
|  | 
 | ||
|  | protected slots: | ||
|  |     bool saveToFile(); | ||
|  |     void startTimeLog(); | ||
|  |     void endTimeLog(); | ||
|  |     void updateTime(); | ||
|  | 
 | ||
|  | private: | ||
|  |     LoggerModeWidgetData* d; | ||
|  | }; | ||
|  | \endcode   | ||
|  | 
 | ||
|  | \section2 Step 3. Implementing the "LoggerModeWidget" class | ||
|  | Declaring the private member variables in the structure called  \bold {LoggerModeWidgetData} | ||
|  | \code | ||
|  | struct LoggerModeWidgetData | ||
|  | { | ||
|  |     QLabel *progressLabel; | ||
|  |     QLabel *hoursWorkedLabel; | ||
|  |     QLabel *dateLabel; | ||
|  |     QLabel *descriptionLabel; | ||
|  |     QCalendarWidget *calendar; | ||
|  |     QComboBox *progressComboBox; | ||
|  |     QLineEdit *hoursWorkedLineEdit; | ||
|  |     QPushButton *startTimerButton; | ||
|  |     QPushButton *stopTimerButton; | ||
|  |     QPushButton *saveButton; | ||
|  |     QTimer *timer; | ||
|  |     QTextEdit *textEdit; | ||
|  |     QString projectName; | ||
|  |     int totalTime; | ||
|  | }; | ||
|  | \endcode | ||
|  | Implementation of the  constructor and destructor of the \bold {LoggerModeWidget} class  | ||
|  | \code | ||
|  | LoggerModeWidget::LoggerModeWidget(const QString projectName, QWidget* parent) | ||
|  | :QWidget(parent) | ||
|  | { | ||
|  |     d = new LoggerModeWidgetData; | ||
|  |     d->projectName = projectName; | ||
|  |     d->totalTime = 0; | ||
|  | 
 | ||
|  |     QStringList percentList; | ||
|  |     percentList <<"10%" <<"20%" <<"30%" <<"40%" <<"50%" | ||
|  |                 <<"60%" <<"70%" <<"80%" <<"90%" <<"100%" ; | ||
|  |     d->progressLabel = new QLabel("Progress:"); | ||
|  |     d->hoursWorkedLabel = new QLabel("Hours Worked:"); | ||
|  |     d->dateLabel = new QLabel("Date:"); | ||
|  |     d->descriptionLabel = new QLabel("Description :"); | ||
|  |     d->hoursWorkedLineEdit = new QLineEdit; | ||
|  |     d->hoursWorkedLineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); | ||
|  |     d->progressComboBox = new QComboBox; | ||
|  |     d->progressComboBox->addItems(percentList); | ||
|  |     d->progressComboBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); | ||
|  |     d->startTimerButton = new QPushButton(tr("Start Timer")); | ||
|  |     d->startTimerButton->setFixedWidth(80); | ||
|  |     d->stopTimerButton = new QPushButton(tr("Pause Timer")); | ||
|  |     d->stopTimerButton->setFixedWidth(80); | ||
|  |     d->stopTimerButton->setCheckable(true); | ||
|  |     d->textEdit = new QTextEdit(this); | ||
|  |     d->textEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||
|  |     d->calendar = new QCalendarWidget; | ||
|  |     d->saveButton = new QPushButton(tr("Save To File")); | ||
|  |     d->saveButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); | ||
|  | 
 | ||
|  |     QGroupBox *timeLoggerBox = new QGroupBox(tr("Time Logger")); | ||
|  | 
 | ||
|  |     QGridLayout *gLayout = new QGridLayout; | ||
|  |     gLayout->addWidget(d->dateLabel, 0, 0, 1, 1); | ||
|  |     gLayout->addWidget(d->calendar, 1, 0, 1, 3); | ||
|  |     gLayout->addWidget(d->progressLabel, 2, 0, 1, 1); | ||
|  |     gLayout->addWidget(d->progressComboBox, 2, 1, 1, 1); | ||
|  |     gLayout->addWidget(d->hoursWorkedLabel, 3, 0, 1, 1); | ||
|  |     gLayout->addWidget(d->hoursWorkedLineEdit, 3, 1, 1, 1); | ||
|  |     gLayout->addWidget(d->startTimerButton, 4, 1, 1, 1); | ||
|  |     gLayout->addWidget(d->stopTimerButton, 4, 2, 1, 1); | ||
|  | 
 | ||
|  |     timeLoggerBox->setLayout(gLayout); | ||
|  | 
 | ||
|  |     d->timer = new QTimer(this); | ||
|  | 
 | ||
|  |     // connection of SIGNALS and SLOTS | ||
|  | 
 | ||
|  |     connect(d->timer, SIGNAL(timeout()), this, SLOT(updateTime())); | ||
|  |     connect(d->startTimerButton,SIGNAL(clicked()),this,SLOT(startTimeLog())); | ||
|  |     connect(d->stopTimerButton,SIGNAL(clicked()),this,SLOT(endTimeLog())); | ||
|  |     connect(d->saveButton, SIGNAL(clicked()), this, SLOT(saveToFile())); | ||
|  | 
 | ||
|  |     QVBoxLayout *vLayout = new QVBoxLayout; | ||
|  |     vLayout->addWidget(d->descriptionLabel); | ||
|  |     vLayout->addWidget(d->textEdit); | ||
|  | 
 | ||
|  |     QHBoxLayout * hLayout = new QHBoxLayout; | ||
|  |     hLayout->addWidget(timeLoggerBox); | ||
|  |     hLayout->addLayout(vLayout); | ||
|  | 
 | ||
|  |     QHBoxLayout *bLayout = new QHBoxLayout; | ||
|  |     bLayout->addStretch(1); | ||
|  |     bLayout->addWidget(d->saveButton); | ||
|  | 
 | ||
|  |     QVBoxLayout *mainLayout = new QVBoxLayout(this); | ||
|  |     mainLayout->addLayout(hLayout); | ||
|  |     mainLayout->addLayout(bLayout); | ||
|  |     mainLayout->addStretch(1); | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | LoggerModeWidget::~LoggerModeWidget() | ||
|  | { | ||
|  |     delete d; | ||
|  | } | ||
|  | 
 | ||
|  | \endcode | ||
|  | 
 | ||
|  | The \bold {saveToFile()} slot is used by the "SaveTofile" button to save the contents of the "LoggerModeWidget" to a  | ||
|  | text file. | ||
|  | \code | ||
|  | bool LoggerModeWidget::saveToFile() | ||
|  | { | ||
|  |     QString fileName = QFileDialog::getSaveFileName(this); | ||
|  |     if (fileName.isEmpty()) | ||
|  |         return false; | ||
|  | 
 | ||
|  |     QFile file(fileName); | ||
|  |     if (!file.open(QFile::WriteOnly | QFile::Text)) { | ||
|  |         QMessageBox::critical(this, tr("Application"), | ||
|  |                              tr("Unable to open file %1 for writing :\n%2.") | ||
|  |                              .arg(fileName) | ||
|  |                              .arg(file.errorString())); | ||
|  |         return false; | ||
|  |     } | ||
|  | 
 | ||
|  |     QTextStream out(&file); | ||
|  | 
 | ||
|  | #ifndef QT_NO_CURSOR | ||
|  |     QApplication::setOverrideCursor(Qt::WaitCursor); | ||
|  | #endif | ||
|  |     out << "Project name : " << d->projectName << "\n"; | ||
|  |     out << "Date         : " << d->calendar->selectedDate().toString() << "\n"; | ||
|  |     out << "Progress     : " << d->progressComboBox->currentText() << "\n"; | ||
|  |     out << "Duration     : " << d->hoursWorkedLineEdit->text() << "\n\n"; | ||
|  |     out << "Description  : " << d->textEdit->toPlainText(); | ||
|  | #ifndef QT_NO_CURSOR | ||
|  |     QApplication::restoreOverrideCursor(); | ||
|  | #endif | ||
|  | 
 | ||
|  |     return true; | ||
|  | } | ||
|  | \endcode | ||
|  | The \bold {startTimeLog()} slot is used by the \bold {Start Timer} button to start the timer. | ||
|  | \code | ||
|  | void LoggerModeWidget::startTimeLog() | ||
|  | { | ||
|  |     d->totalTime = 0; | ||
|  |     d->timer->start(1000); | ||
|  | } | ||
|  | \endcode | ||
|  | 
 | ||
|  | The \bold {endTimeLog()} slot is used by the \bold (Pause Timer } button  to pause and resume the timer. | ||
|  | \code | ||
|  | void LoggerModeWidget::endTimeLog() | ||
|  | { | ||
|  |     if(d->stopTimerButton->isChecked()) | ||
|  |     { | ||
|  |         d->stopTimerButton->setText("Continue Timer"); | ||
|  |         d->timer->stop(); | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         d->stopTimerButton->setText("Pause Timer"); | ||
|  |         d->timer->start(1000); | ||
|  |     } | ||
|  | } | ||
|  | \endcode | ||
|  | 
 | ||
|  | The \bold {updateTime()} slot is used to update the time. | ||
|  | \code | ||
|  | void LoggerModeWidget::updateTime() | ||
|  | { | ||
|  |     d->totalTime++; | ||
|  |     QTime time(0,0,0); | ||
|  |     time = time.addSecs(d->totalTime); | ||
|  |     d->hoursWorkedLineEdit->setText(time.toString()); | ||
|  | } | ||
|  | \endcode     | ||
|  | 
 | ||
|  | \section1 13.4 Testing the final LoggerMode plugin. | ||
|  | 
 | ||
|  | \section2 Step 1. A  "LoggerMode" mode selector can be seen int the Qt Creator. | ||
|  | \inlineimage qtc-loggermode-13.png | ||
|  | 
 | ||
|  | \section2 Step 2. A LoggerMode widget opens with options to "Add Projects" | ||
|  | \inlineimage  qtc-loggerpage-13.png | ||
|  | 
 | ||
|  | \section2 Step 3. The "Add Project" button adds a project to the "Current Project list and opens the the "LoggerModeWidget" | ||
|  | \inlineimage  qtc-loggermodewidget-13.png | ||
|  | 
 | ||
|  | */ |