-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue creator to create issues on-the-fly
- Issue creator saves tracked time to the new issue - Issue selector now shows all issues of a project - Title includes Redmine URL - Tray icon shows title as tool tip - Tray icon is now triggered by a single click - RedTimer icon in the executable - Executable contains version information etc. - Icons in the application are a bit smaller - The settings dialogue, issue selector and issue creator are now displayed as a dialogue window
- Loading branch information
Frederick Thomssen
committed
Apr 15, 2016
1 parent
1ca175f
commit 076cb11
Showing
24 changed files
with
1,999 additions
and
410 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,3 +73,5 @@ Thumbs.db | |
# gh-pages | ||
html | ||
/*.ini | ||
/redtimer_plugin_import.cpp | ||
/redtimer_qml_plugin_import.cpp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,256 @@ | ||
#include "IssueCreator.h" | ||
#include "IssueSelector.h" | ||
#include "logging.h" | ||
|
||
#include <QSortFilterProxyModel> | ||
|
||
using namespace qtredmine; | ||
using namespace redtimer; | ||
using namespace std; | ||
|
||
IssueCreator::IssueCreator( SimpleRedmineClient* redmine, QQuickView* parent ) | ||
: Window( "qrc:/IssueCreator.qml", parent ), | ||
redmine_( redmine ) | ||
{ | ||
ENTER(); | ||
|
||
// Issue selector window initialisation | ||
setResizeMode( QQuickView::SizeRootObjectToView ); | ||
setModality( Qt::ApplicationModal ); | ||
setFlags( Qt::Dialog ); | ||
setTitle( "Issue Creator" ); | ||
|
||
// Load projects | ||
QSortFilterProxyModel* projectProxyModel = new QSortFilterProxyModel(); | ||
projectProxyModel->setSourceModel( &projectModel_ ); | ||
projectProxyModel->setSortRole( SimpleModel::SimpleRoles::IdRole ); | ||
ctx_->setContextProperty( "projectModel", projectProxyModel ); | ||
|
||
loadProjects(); | ||
|
||
// Load trackers | ||
QSortFilterProxyModel* trackerProxyModel = new QSortFilterProxyModel(); | ||
trackerProxyModel->setSourceModel( &trackerModel_ ); | ||
trackerProxyModel->setSortRole( SimpleModel::SimpleRoles::IdRole ); | ||
ctx_->setContextProperty( "trackerModel", trackerProxyModel ); | ||
|
||
loadTrackers(); | ||
|
||
// Connect the project selected signal to the projectSelected slot | ||
connect( qml("project"), SIGNAL(activated(int)), this, SLOT(projectSelected(int)) ); | ||
|
||
// Connect the tracker selected signal to the trackerSelected slot | ||
connect( qml("tracker"), SIGNAL(activated(int)), this, SLOT(trackerSelected(int)) ); | ||
|
||
// Connect the issue selector button | ||
connect( qml("selectParentIssue"), SIGNAL(clicked()), this, SLOT(selectParentIssue()) ); | ||
|
||
// Connect the create button clicked signal to the save slot | ||
connect( qml("create"), SIGNAL(clicked()), this, SLOT(save()) ); | ||
|
||
// Connect the cancel button clicked signal to the close slot | ||
connect( qml("cancel"), SIGNAL(clicked()), this, SLOT(closeWin()) ); | ||
|
||
// Connect the closed signal to the close slot | ||
connect( this, &Window::closed, [=](){ closeWin(); } ); | ||
|
||
RETURN(); | ||
} | ||
|
||
IssueCreator::~IssueCreator() | ||
{ | ||
ENTER(); | ||
RETURN(); | ||
} | ||
|
||
void | ||
IssueCreator::closeWin() | ||
{ | ||
ENTER(); | ||
|
||
if( isVisible() ) | ||
{ | ||
DEBUG() << "Closing issue creator window"; | ||
if( cancelOnClose_ ) | ||
cancelled(); | ||
close(); | ||
} | ||
|
||
RETURN(); | ||
} | ||
|
||
void | ||
IssueCreator::display() | ||
{ | ||
ENTER(); | ||
|
||
if( !isVisible() ) | ||
{ | ||
DEBUG() << "Displaying issue creator window"; | ||
show(); | ||
} | ||
|
||
RETURN(); | ||
} | ||
|
||
void | ||
IssueCreator::loadProjects() | ||
{ | ||
ENTER(); | ||
|
||
redmine_->retrieveProjects( [&]( Projects projects ) | ||
{ | ||
ENTER(); | ||
|
||
projectModel_.clear(); | ||
projectModel_.push_back( SimpleItem(NULL_ID, "Choose project") ); | ||
for( const auto& project : projects ) | ||
projectModel_.push_back( SimpleItem(project) ); | ||
|
||
qml("project")->setProperty( "currentIndex", -1 ); | ||
qml("project")->setProperty( "currentIndex", 0 ); | ||
|
||
RETURN(); | ||
} ); | ||
|
||
RETURN(); | ||
} | ||
|
||
void | ||
IssueCreator::loadTrackers() | ||
{ | ||
ENTER(); | ||
|
||
redmine_->retrieveTrackers( [&]( Trackers trackers ) | ||
{ | ||
ENTER(); | ||
|
||
trackerModel_.clear(); | ||
trackerModel_.push_back( SimpleItem(NULL_ID, "Choose tracker") ); | ||
for( const auto& tracker : trackers ) | ||
trackerModel_.push_back( SimpleItem(tracker) ); | ||
|
||
qml("tracker")->setProperty( "currentIndex", -1 ); | ||
qml("tracker")->setProperty( "currentIndex", 0 ); | ||
|
||
RETURN(); | ||
} ); | ||
|
||
RETURN(); | ||
} | ||
|
||
void | ||
IssueCreator::projectSelected( int index ) | ||
{ | ||
ENTER(); | ||
|
||
projectId_ = projectModel_.at(index).id(); | ||
DEBUG()(index)(projectId_); | ||
|
||
RETURN(); | ||
} | ||
|
||
void | ||
IssueCreator::save() | ||
{ | ||
ENTER(); | ||
|
||
if( projectId_ == NULL_ID ) | ||
{ | ||
message( "Please select a project", QtCriticalMsg ); | ||
RETURN(); | ||
} | ||
|
||
if( trackerId_ == NULL_ID ) | ||
{ | ||
message( "Please select a tracker", QtCriticalMsg ); | ||
RETURN(); | ||
} | ||
|
||
if( qml("subject")->property("text").toString().isEmpty() ) | ||
{ | ||
message( "Please specify a subject", QtCriticalMsg ); | ||
RETURN(); | ||
} | ||
|
||
cancelOnClose_ = false; | ||
|
||
Issue issue; | ||
issue.project.id = projectId_; | ||
issue.tracker.id = trackerId_; | ||
|
||
if( !qml("parentIssue")->property("text").toString().isEmpty() ) | ||
issue.parentId = qml("parentIssue")->property("text").toInt(); | ||
|
||
if( !qml("parentIssue")->property("estimatedTime").toString().isEmpty() ) | ||
issue.estimatedHours = qml("estimatedTime")->property("text").toDouble(); | ||
|
||
issue.subject = qml("subject")->property("text").toString(); | ||
issue.description = qml("description")->property("text").toString(); | ||
|
||
redmine_->sendIssue( issue, [=](bool success, int id, RedmineError errorCode, QStringList errors) | ||
{ | ||
ENTER()(success)(id)(errorCode)(errors); | ||
|
||
if( !success ) | ||
{ | ||
cancelOnClose_ = true; | ||
|
||
QString errorMsg = tr( "Could not create issue." ); | ||
for( const auto& error : errors ) | ||
errorMsg.append("\n").append(error); | ||
|
||
message( errorMsg, QtCriticalMsg ); | ||
RETURN(); | ||
} | ||
|
||
message( tr("New issue created with ID %1").arg(id) ); | ||
|
||
created( id ); | ||
closeWin(); | ||
|
||
RETURN(); | ||
} ); | ||
|
||
RETURN(); | ||
} | ||
|
||
void | ||
IssueCreator::selectParentIssue() | ||
{ | ||
// Issue selector initialisation | ||
IssueSelector* issueSelector = new IssueSelector( redmine_ ); | ||
issueSelector->setTransientParent( this ); | ||
if( projectId_ != NULL_ID ) | ||
issueSelector->setProjectId( projectId_ ); | ||
issueSelector->display(); | ||
|
||
// Connect the issue selected signal to the setIssue slot | ||
connect( issueSelector, &IssueSelector::selected, [=](int issueId) | ||
{ | ||
qml("parentIssue")->setProperty( "text", issueId ); | ||
issueSelector->close(); | ||
} ); | ||
} | ||
|
||
void | ||
IssueCreator::setParentIssueId( int id ) | ||
{ | ||
ENTER(); | ||
|
||
if( id != NULL_ID ) | ||
qml("parentIssue")->setProperty( "text", id ); | ||
|
||
RETURN(); | ||
} | ||
|
||
void | ||
IssueCreator::trackerSelected( int index ) | ||
{ | ||
ENTER(); | ||
|
||
trackerId_ = trackerModel_.at(index).id(); | ||
DEBUG()(index)(trackerId_); | ||
|
||
RETURN(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
#ifndef ISSUECREATOR_H | ||
#define ISSUECREATOR_H | ||
|
||
#include "Models.h" | ||
#include "Window.h" | ||
#include "qtredmine/SimpleRedmineClient.h" | ||
|
||
namespace redtimer { | ||
|
||
/** | ||
* @brief An issue creator for RedTimer | ||
*/ | ||
class IssueCreator : public Window | ||
{ | ||
Q_OBJECT | ||
|
||
private: | ||
/// Redmine connection object | ||
qtredmine::SimpleRedmineClient* redmine_ = nullptr; | ||
|
||
/// Emit the cancelled signal upon closing | ||
bool cancelOnClose_ = true; | ||
|
||
/// Current project | ||
int projectId_ = NULL_ID; | ||
|
||
/// Cached projects | ||
SimpleModel projectModel_; | ||
|
||
/// Current tracker | ||
int trackerId_ = NULL_ID; | ||
|
||
/// Cached trackers | ||
SimpleModel trackerModel_; | ||
|
||
private: | ||
/** | ||
* @brief Load and refresh projects in the GUI | ||
*/ | ||
void loadProjects(); | ||
|
||
/** | ||
* @brief Load and refresh trackers in the GUI | ||
*/ | ||
void loadTrackers(); | ||
|
||
public: | ||
/** | ||
* @brief Constructor for an IssueCreator object | ||
* | ||
* @param redmine Redmine connection object | ||
* @param parent Parent QObject | ||
*/ | ||
explicit IssueCreator( qtredmine::SimpleRedmineClient* redmine, QQuickView* parent = nullptr ); | ||
|
||
/** | ||
* @brief Destructor | ||
*/ | ||
~IssueCreator(); | ||
|
||
/// @name Setters | ||
/// @{ | ||
|
||
/** | ||
* @brief Set the parent issue ID | ||
* | ||
* @param id Parent issue ID | ||
*/ | ||
void setParentIssueId( int id ); | ||
|
||
/// @} | ||
|
||
public slots: | ||
/** | ||
* @brief Close the issue selector dialog | ||
*/ | ||
void closeWin(); | ||
|
||
/** | ||
* @brief Display the issue selector dialog | ||
*/ | ||
void display(); | ||
|
||
private slots: | ||
/** | ||
* @brief Slot to a selected project | ||
*/ | ||
void projectSelected( int index ); | ||
|
||
/** | ||
* @brief Save the new issue | ||
*/ | ||
void save(); | ||
|
||
/** | ||
* @brief Open the issue selector and load issue | ||
*/ | ||
void selectParentIssue(); | ||
|
||
/** | ||
* @brief Slot to a selected tracker | ||
*/ | ||
void trackerSelected( int index ); | ||
|
||
signals: | ||
/** | ||
* @brief Emitted when the issue creator has been cancelled | ||
*/ | ||
void cancelled(); | ||
|
||
/** | ||
* @brief Emitted when an issue has been created | ||
*/ | ||
void created( int issueId ); | ||
|
||
}; | ||
|
||
} // redtimer | ||
|
||
#endif // ISSUECREATOR_H |
Oops, something went wrong.