diff options
Diffstat (limited to 'client/mainwindow.cc')
-rw-r--r-- | client/mainwindow.cc | 575 |
1 files changed, 575 insertions, 0 deletions
diff --git a/client/mainwindow.cc b/client/mainwindow.cc new file mode 100644 index 0000000..ce3d9bb --- /dev/null +++ b/client/mainwindow.cc @@ -0,0 +1,575 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * mainwindow.cc + * + * Sat Aug 21 19:49:34 2004 + * Copyright 2004 deva + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of MIaV. + * + * MIaV is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MIaV is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MIaV; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include <config.h> +#ifdef USE_GUI + +#include "mainwindow.h" + +#include <qpainter.h> +#include <qpicture.h> + +#include <qpushbutton.h> +#include <qfont.h> +#include <qpixmap.h> +#include <qbitmap.h> +#include <qimage.h> +#include <qlayout.h> +#include <qgroupbox.h> + +#include <qstatusbar.h> + +#include <math.h> + +//#include "mgui_alert.h" +//#include "mgui_datasocket.h" + +#include "miav_config.h" + +#include <config.h> +//"miav-grab.h" + +//#define WITH_DV +MainWindow::MainWindow(QApplication *qApp, QWidget* parent, const char* name ) + : QWidget( parent, name, WStyle_Customize | WStyle_NoBorder ) +{ + info = new InfoGui(qApp, this, config); + + info->log("Starting MIaV v. %s.", VERSION); + + video_width = config->readInt("video_width"); + video_height = config->readInt("video_height"); + + int resolution_w = config->readInt("pixel_width"); + int resolution_h = config->readInt("pixel_height"); + + unit = ((float)resolution_w / config->readFloat("screensize")) / INCH_IN_CM; + + printf("Unit: %f\n", unit); + + move(0,0); + resize(resolution_w, resolution_h); + + // Load icons + img_record = loadButtonIcon( PIXMAP_RECORD ); + img_stop = loadButtonIcon( PIXMAP_STOP ); + img_freeze = loadButtonIcon( PIXMAP_FREEZE ); + img_unfreeze = loadButtonIcon( PIXMAP_UNFREEZE ); + img_cpr = loadButtonIcon( PIXMAP_CPR ); + img_clear = loadButtonIcon( PIXMAP_CLEAR ); + img_snapshot = loadButtonIcon( PIXMAP_SNAPSHOT ); + img_logo = loadButtonIcon( PIXMAP_LOGO_SMALL, 1 ); + img_mute = loadButtonIcon( PIXMAP_MUTE ); + img_unmute = loadButtonIcon( PIXMAP_UNMUTE ); + + img_dummy = loadImage( PIXMAP_DUMMY ); + + timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), SLOT(redraw_edge())); + rec_edge_counter = 0.0f; + + // This must be defined before the gui i created (img_live uses it as parameter) + camera = new Camera(info); + + createGui(); + show(); + + camera->connect(config->readString("server_addr")->c_str(), + config->readInt("server_port"), + img_live->width(), img_live->height()); + + // Make sure this is created *after* the camera object! + taskbartimer = new QTimer(this); + connect(taskbartimer, SIGNAL(timeout()), SLOT(taskbar_update())); + taskbartimer->start(200); + + recording = false; + frozen = false; + muted = false; + + info->log("MIaV is ready."); + + // Open the CPR Dialog + cpr_clicked(); + +} + +MainWindow::~MainWindow() +{ + info->log("MIaV is shutting down."); + + delete img_history; + delete camera; + delete btn_cpr; + + info->log("MIaV is shut down."); +} + +QImage *MainWindow::loadButtonIcon( char *name, int height ) +{ + + QImage scaled; + QImage *img; + + img = new QImage(); + img->load( name ); + + int h = (int)(height * unit); + int w = (int)((float)img->width() / (float)(img->height() / (float)h)); + + scaled = img->smoothScale(w, h); + delete img; + img = new QImage(scaled); + + return img; +} + +QImage *MainWindow::loadImage( char *name ) +{ + QImage *img; + + img = new QImage(); + img->load( name ); + + return img; +} + +void MainWindow::createGui() +{ + // Layout widgets + + /* __________________________________________________ + *(0) ___________________________ | ______________ | + * | | | | | | | | | | + * |(1) | | | | |(2) | | + * | | | | | | | | | | + * | | | | | | | | | | + * | | | | | | | |______________| | + * | | | | | | | | | | + * | | | | | | | | | | + * | | | | | | | | | | + * | |______|______|______|______| | | | | + * | | | | | | | |______________| | + * | |______|______|______|______| | | | | + * | | | | | | | | | | + * | |______|______|______|______| | | | | + * | | | | | | | | | | + * | |______|______|______|______| | |______________| | + * |_______________________________|__________________| + * |_______________________________|__________________| + */ + + QGridLayout *g0 = new QGridLayout(this, 2, 2, 0, -1); + QGridLayout *g1 = new QGridLayout(4, 4, -1); + g0->addLayout(g1, 0, 0); + + QGroupBox *gb = new QGroupBox(this); + // gb->setRows(NUM_HISTORY); + gb->setColumns(1); + // gb->setTitle("fisk"); + // QGridLayout *g2 = new QGridLayout(1, NUM_HISTORY, -1); + // QVBoxLayout *g2 = new QVBoxLayout(this); + // g0->addLayout(g2, 0, 1); + + gb->setInsideMargin(HISTORY_LIST_MARGIN); + gb->setInsideSpacing(HISTORY_LIST_SPACING); + gb->setFlat(true); + g0->addWidget(gb, 0, 1); + + int resolution_w = config->readInt("pixel_width"); + int resolution_h = config->readInt("pixel_height"); + + int output_width = resolution_w - // this->width() - + (int)(BUTTON_WIDTH * unit) - + (gb->insideMargin() * 2) - + g1->margin() * 2 - + g0->margin() * 2; + + int output_height = resolution_h - // this->height() - + (int)(3 * BUTTON_HEIGHT * unit) - + g1->margin() * 5 - + g0->margin() * 3; + + img_recedge = new QLabel(this); + img_recedge->setBackgroundColor(QColor(160,160,160)); + img_recedge->setFixedSize(output_width, output_height); + + img_live = new VideoWidget(img_recedge, camera); + img_live->setFixedSize(output_width - 20, output_height - 20); + img_live->move(10,10); + g1->addMultiCellWidget ( img_recedge, 0, 0, 0, 3, Qt::AlignHCenter); + // QObject::connect( img_live, SIGNAL(clicked()), this, SLOT(live_clicked()) ); + + // CPR/NAME LABEL + CPR button + lbl_cpr = createLabel("", output_width - (int)(BUTTON_WIDTH * unit), BUTTON_HEIGHT); + g1->addMultiCellWidget ( lbl_cpr, 1, 1, 0, 2); + + btn_cpr = createButton(""); + btn_cpr->setFocus(); + btn_cpr->setPixmap(*img_cpr); + QObject::connect( btn_cpr, SIGNAL(clicked()), this, SLOT(cpr_clicked()) ); + // Will also be connected in the MGUI code + g1->addWidget(btn_cpr, 1, 3); + + lbl_name = createLabel("", output_width, (int)(BUTTON_HEIGHT * 0.8f)); + g1->addMultiCellWidget ( lbl_name, 2, 2, 0, 3); +/* + btn_clear = createButton(""); + btn_clear->setPixmap(*img_clear); + QObject::connect( btn_clear, SIGNAL(clicked()), this, SLOT(clear_clicked()) ); + // Will also be connected in the MGUI code + g1->addWidget(btn_clear, 1, 2); +*/ + // Rec + Shot + Freeze buttons + btn_rec = createButton(""); + btn_rec->setPixmap(*img_record); + QObject::connect( btn_rec, SIGNAL(clicked()), this, SLOT(rec_clicked()) ); + g1->addWidget(btn_rec, 3, 0); + + btn_shoot = createButton(""); + btn_shoot->setPixmap(*img_snapshot); + QObject::connect( btn_shoot, SIGNAL(clicked()), this, SLOT(shoot_clicked()) ); + g1->addWidget(btn_shoot, 3, 1); + + btn_freeze = createButton(""); + btn_freeze->setPixmap(*img_freeze); + QObject::connect( btn_freeze, SIGNAL(clicked()), this, SLOT(freeze_clicked()) ); + g1->addWidget(btn_freeze, 3, 2); + + btn_mute = createButton(""); + btn_mute->setPixmap(*img_unmute); + QObject::connect( btn_mute, SIGNAL(clicked()), this, SLOT(mute_clicked()) ); + g1->addWidget(btn_mute, 3, 3); + + // History widgets + int w = (int)((float)BUTTON_WIDTH * unit); + int h = (int)(576.0f / (720.0f / ((float)BUTTON_WIDTH * unit))); + + int window_height = config->readInt("pixel_height"); + this->num_history = (window_height - + ((int)unit * BUTTON_HEIGHT + HISTORY_LIST_SPACING ) - + (2 * HISTORY_LIST_MARGIN)) / (h + HISTORY_LIST_SPACING); + img_history = new HistoryWidget*[this->num_history]; + + for(unsigned int i = 0; i < num_history; i++) { + img_history[i] = new HistoryWidget(gb); + img_history[i]->set_image(img_dummy); + img_history[i]->setFixedSize(w, h); + } + + // Clear button + btn_clear = createButton("", gb); + btn_clear->setPixmap(*img_clear); + QObject::connect( btn_clear, SIGNAL(clicked()), this, SLOT(clear_clicked()) ); + + // Statusbar + status = new QStatusBar(this); + status->setSizeGripEnabled(FALSE); + // status->setFont(QFont( "Sans Serif", (int)(unit * height / 3), QFont::Normal )); + g0->addMultiCellWidget(status, 4, 4, 0, 1); + + lbl_recordtime = createLabel("", BUTTON_WIDTH, 1); + lbl_recordtime->setFixedWidth((int)(BUTTON_WIDTH * unit) + + (gb->insideMargin() * 2) + + g1->margin() * 2 + + g0->margin() * 2); + status->addWidget(lbl_recordtime, 0, TRUE); + + // About button + btn_about = new QPushButton("", this); + btn_about->setFixedHeight((int)unit); + btn_about->setPixmap(*img_logo); + QObject::connect( btn_about, SIGNAL(clicked()), this, SLOT(about_clicked()) ); + status->addWidget(btn_about, 0, TRUE); + + // Version label + lbl_version = createLabel("MIaV-Grab v" VERSION, BUTTON_WIDTH, 1); + lbl_version->setFixedWidth((int)(BUTTON_WIDTH * unit) + + (gb->insideMargin() * 2) + + g1->margin() * 2 + + g0->margin() * 2); + status->addWidget(lbl_version, 0, TRUE); + + status->message( TXT_READY ); +} + + +QPushButton *MainWindow::createButton(char *caption, int width, int height) +{ + return createButton(caption, this);//, width, height); +} + + +QPushButton *MainWindow::createButton(char *caption, QWidget *parent, int width, int height) +{ + QPushButton *btn = new QPushButton(caption, parent); + btn->setFont( QFont( "Sans Serif", (int)(unit * height / 2), QFont::Bold ) ); + btn->setFixedHeight((int)(unit * height)); + // btn->setFixedWidth((int)(unit * width)); + return btn; +} + + +QLabel *MainWindow::createLabel(char *caption, int width, int height) +{ + QLabel *lbl = new QLabel(caption, this); + lbl->setFont( QFont( "Sans Serif", + //(height>1)?(int)(unit * height / 2):(int)(unit * height / 2), + (int)(unit * height / 2), + (height>1)?QFont::Bold:QFont::Normal ) ); + lbl->setFixedHeight((int)(unit * height)); + // lbl->setFixedWidth((int)(unit * width)); + return lbl; +} + +#include <sys/time.h> +static struct timeval starttime; +static int h = 0; +static int m = 0; +static int s = 0; +static int watchdog = 0; + +void MainWindow::taskbar_update() +{ + struct timeval time; + watchdog++; + + if(recording) { + if((watchdog % 300 == 0) || ((camera->getQueueLength() > 1000) && (watchdog % 50 == 0))) + info->log("Queue length: %d (active)", camera->getQueueLength()); + + gettimeofday(&time, NULL); + + s = time.tv_sec - starttime.tv_sec; + + h = s / (60 * 60); + s -= h * (60 * 60); + m = s / 60; + s -= m * 60; + } else { + if((camera->getQueueLength() > 0) && (watchdog % 300 == 0)) + info->log("Queue length: %d (passive)", camera->getQueueLength()); + gettimeofday(&starttime, NULL); + } + + char msg[256]; + int l = camera->getQueueLength(); + sprintf(msg, TXT_TIME " %.02d:%.02d:%.02d " TXT_QUEUELENGTH " %d", h, m, s, l); + lbl_recordtime->setText(msg); +} + +#define GREY 160 +#define SPEED 0.07f +void MainWindow::redraw_edge() +{ + rec_edge_counter += SPEED; + float val = fabs(sin(rec_edge_counter)); + img_recedge->setBackgroundColor(QColor((int) ((255 - GREY) * val + GREY), + (int) (GREY - (GREY * val)), + (int) (GREY - (GREY * val)))); +} + +void MainWindow::message(char *msg) +{ + status->message(msg); + info->log("Message: %s", msg); +} + +void MainWindow::clear() +{ + info->log("Clearing screen."); + + + // History widgets + for(unsigned int i = 0; i < num_history; i++) { + img_history[i]->set_image(img_dummy); + } + + lbl_name->setText(""); + lbl_cpr->setText(""); +} + +#include "aboutwindow.h" +void MainWindow::about_clicked() +{ + AboutWindow about; + about.exec(); +} + +void MainWindow::clear_clicked() +{ + if(MessageBox(this, + TXT_ASK_CLEAR_SCREEN_TITLE, + TXT_ASK_CLEAR_SCREEN, + TYPE_YES_NO, + ICON_QUESTION).exec() == MSG_YES) { + clear(); + } +} + +void MainWindow::cpr_clicked() +{ + char oldcpr[256]; + char oldname[256]; + + // If recording, stop recording before changingcpr + if(recording) { + MessageBox(this, + TXT_STOP_RECORDING_TITLE, + TXT_STOP_RECORDING, + TYPE_OK, + ICON_WARNING).exec(); + return; + } + info->log("Activated CPR chooser."); + + // Save CPR and name, from the labels. + strcpy(oldname, lbl_name->text().ascii()); + strcpy(oldcpr, lbl_cpr->text().ascii()); + + clear(); + + // Create and call the CPRQueryDialog. + CPRQueryDialog dlg(info, lbl_cpr, lbl_name, this, TXT_CPRDLG_TITLE, status); + + if(dlg.exec() == 0) { + // Restore old CPR and name, in the labels. + lbl_name->setText(oldname); + lbl_cpr->setText(oldcpr); + info->log("Cancelled CPR chooser."); + } else { + // Change CPR camera. + info->log("New CPR %s (old %s).", (char*)lbl_cpr->text().ascii(), oldcpr); + strcpy(oldname, lbl_name->text().ascii()); + strcpy(oldcpr, lbl_cpr->text().ascii()); + clear(); + lbl_name->setText(oldname); + lbl_cpr->setText(oldcpr); + camera->setCpr((char*)lbl_cpr->text().ascii(), (char*)lbl_name->text().ascii()); + } +} + +void MainWindow::rec_clicked() +{ + if(!recording) { + info->log("Start recording."); + recording = 1; + // Start flashing the edge + rec_edge_counter = 0.0f; + timer->start(100); + btn_rec->setPixmap(*img_stop); + camera->start(); + } else { + switch(MessageBox(this, + TXT_ASK_SAVE_TITLE, + TXT_ASK_SAVE, + TYPE_YES_NO_MAYBE_CANCEL, + ICON_QUESTION).exec()) { + case MSG_YES: + info->log("Stop recording (Said yes to save)."); + recording = 0; + camera->stop(SAVE); + timer->stop(); + img_recedge->setBackgroundColor(QColor(160,160,160)); + btn_rec->setPixmap(*img_record); + break; + + case MSG_NO: + info->log("Stop recording (Said no to save)."); + recording = 0; + camera->stop(DELETE); + timer->stop(); + img_recedge->setBackgroundColor(QColor(160,160,160)); + btn_rec->setPixmap(*img_record); + break; + + case MSG_MAYBE: + info->log("Stop recording (Said maybe to save)."); + recording = 0; + camera->stop(LATER); + timer->stop(); + img_recedge->setBackgroundColor(QColor(160,160,160)); + btn_rec->setPixmap(*img_record); + break; + + case MSG_CANCEL: + info->log("Didn't stop recording (canceled)."); + break; + } + } +} + +void MainWindow::shoot_clicked() +{ + // unsigned char pixels[720*576*3]; + info->log("Snapshot (%s).", frozen?"frozen":"unfrozen"); + + QImage screenshot(720, 576, 32); + + camera->snapshot(screenshot.bits()); + + QImage *image; + for(int cnt = (num_history-1); cnt > 0; cnt--) { + image = img_history[cnt-1]->get_image(); + img_history[cnt]->set_image(image); + } + img_history[0]->set_image(&screenshot); + + if(frozen) { + camera->unfreeze(); + btn_freeze->setPixmap(*img_freeze); + btn_freeze->setOn(false); + frozen = false; + } +} + +void MainWindow::freeze_clicked() +{ + if(frozen) { + info->log("Unfreeze."); + camera->unfreeze(); + btn_freeze->setPixmap(*img_freeze); + btn_freeze->setOn(false); + frozen = false; + } else { + info->log("Freeze."); + camera->freeze(); + btn_freeze->setPixmap(*img_unfreeze); + btn_freeze->setOn(true); + frozen = true; + } +} + +void MainWindow::mute_clicked() +{ + muted = !muted; + if(muted) btn_mute->setPixmap(*img_mute); + else btn_mute->setPixmap(*img_unmute); + + camera->setMute(muted); +} + +#endif /*USE_GUI*/ |