Разработка для SailfishOS: таймеры и реализация экспорта в файл

от автора

Мы уже писали про опыт разработки нашего первого приложения для мобильной платформы Sailfish OS. Но на этом решили не останавливаться и сразу взялись за второе. Целью было создать приложение, с помощью которого пользователь мог бы вести учёт своего рабочего времени, планировать задачи и предоставлять информацию о проделанной работе, иными словами – разработать персональный мобильный тайм-трекер.

Описание приложения

Приложение, естественно, должно уметь вести журнал задач с возможность сохранения времени, потраченного на них. Желательно было, чтобы время можно было засекать с помощью встроенного таймера, а не только прописывать руками. Кроме этого, планировалась возможность создание текстовых отчетов о проделанной работе, в виде таблиц, с последующей отправкой их работодателю.

Так как разработка самой структуры приложения и его интерфейса уже была описана в предыдущих статьях цикла разработки для Sailfish OS (путь от начала разработки до создания первого приложения вы можете отследить здесь и тут), то в этой статье будет описан только функционал, который отличается от реализованного ранее и наиболее интересен с точки зрения его реализации. В нашем приложении — это таймеры задач и экспорт списка задач.

Таймер

Для измерения длительности работ в приложении используется механизм таймера. Процесс отсчета времени осуществляется с помощью стандартного элемента Qt Timer, у которого выставлен интервал обновления 1000 миллисекунд.

Timer {   id: stopwatch   interval: 1000   repeat: true   running: true   triggeredOnStart: true   onTriggered: {     if (timerActive) {       var currentTime = new Date ();       var differeceInTime = (currentTime.getTime() - previousTime.getTime());       previousTime = currentTime;       updateData(differentInTime);     }   } }  function updateData(usec) {   elapsedTime += usec;   taskTimerString = getTimeString(elapsedTime); } 

При каждом срабатывании события onTriggered у Timer происходит вычисление времени таймера: из текущего времени вычитается время предыдущего срабатывания. Такая реализация удобна тем, что при выходе устройства из неактивного режима, время корректно будет обновлятся.

Для управления таймером сделаны кнопки Старт и Сбросить. Так же есть возможность поставить активный таймер на паузу. Чтобы сохранить замеренное время достаточно нажать на кнопку Сохранить время, доступную в выпадающем меню. Замер таймера автоматически добавится к текущему времени, потраченному на задачу.

Если пользователь пытается запустить новый таймер, пока активен старый, то будет выведен диалог с возможностью выбрать, как поступить со старым таймером: сбросить данные старого таймера и начать новый, сохранить данные старого таймера и начать новый, перейти к старому таймеру.

Также, если таймер активен, то он отображается на обложке приложения.

Экспорт отчетов


В приложении также реализована функция создания отчетов. Отчет представляет из себя таблицу, содержащую информацию о всех хранящихся в приложении задачах. В таблицу записываются даты начала и окончания задачи, ее название и описание, статус задачи, а также время, потраченное на нее. Список задач берется напрямую из базы данных, при этом задачи выбираются из промежутка, который пользователь сам указывает на экране создания отчетов.

function selectByPeriod(beginning, end) {   var database = getDatabase();   queryResult.clear();   database.transaction(function(transaction) {     var tasks = transaction.executeSql('SELECT * FROM tasks WHERE startDate >= ? AND finishDate <= ?',  [beginning, end]);     for (var i = 0; i < tasks.rows.length; i++) {       var element = tasks.rows.item(i);       var startDate = new Date (element.startDate);       var finishDate = new Date (element.finishDate);       convertDateToUTC(startDate);       convertDateToUTC(finishDate);       var idDone = element.taskDone === 0 ? false : true       queryResult.append({"startDate": startDate, "finishDate": finishDate, "taskName": element.taskName, "taskDescription": element.taskDescription, "taskDone": isDone, "spentTime": element.spentTime});     }   }) }  

Есть возможность записывать отчеты в файлы двух типов: csv и html. Выбор формата исходного файла происходит также на экране создания отчетов. Для каждого из типов реализован c++ класс, отвечающий за создание соответствующего файла. Запись в csv файлы осуществляется с помощью текстового потока QTextStream. Для корректного отображения кириллицы используется кодировка Windows-1251.

Q_INVOKABLE void writeLine(QVariantList taskInfo) {     QTextCodec *utf8 = QTextCodec::codecForName("Windows-1251");     QTextStream stream(&csvFile);     QStringList line;     stream.setCodec(utf8);     for(int i = 0; i < taskInfo.size(); i++) {         line << taskInfo[i].toString();     }     stream << line.join(",") << endl; } 

HTML отчеты создаются с помощью класса QTextDocument. Для создания таблицы с информацией по задачам используется класс QTextTable. Он позволяет задать стиль таблицы и текста в ней.

Q_INVOKABLE void createDocument(int rows, QVariantList columns) {     report = new QTextDocument();     QTextCursor cursor(report);     table = cursor.insertTable(rows + 1, columns.length());     QTextCharFormat format;     format.setFontWeight(QFont::Bold);     QTextCharFormat cellFormat;     cellFormat.setBackground(QBrush(Qt::cyan));     for(int col = 0; col < table->columns(); col++) {         QTextTableCell cell = table->cellAt(0, col);         QTextCursor cellCursor = cell.firstCursorPosition();         cell.setFormat(cellFormat);         cellCursor.mergeCharFormat(format);         cellCursor.insertText(columns[col].toString());     }     QTextTableFormat tableFormat = cursor.currentTable()->format();     tableFormat.setCellSpacing(0);     table->setFormat(tableFormat); }  Q_INVOKABLE void addRow(int row, QVariantList taskInfo) {     QTextCharFormat cellFormat;     cellFormat.setBackground(QBrush(Qt::darkCyan));     for(int col = 0; col < table->columns(); col++) {         QTextTableCell cell = table->cellAt(row, col);         QTextCursor cellCursor = cell.firstCursorPosition();         cellCursor.insertText(taskInfo[col].toString());     }     QTextTableCell indexCell = table->cellAt(row, 0);     indexCell.setFormat(cellFormat); } 

Заключение

В результате было создано приложение с понятным и простым интерфейсом, которое позволяет легко вести и отслеживать список дел. Из ранее не планируемого функционала была добавлена возможность фильтровать задачи по статусу выполнения, чтобы можно было отсеивать выполненные. Приложение было опубликовано в магазине приложений Jolla Harbour под названием Report Card и доступно для скачивания всем желающим. Исходники приложения доступны на GitHub.

Автор: Максим Костерин
ссылка на оригинал статьи https://habrahabr.ru/post/316082/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *