summaryrefslogtreecommitdiff
path: root/miav/mainwindow.cc
diff options
context:
space:
mode:
Diffstat (limited to 'miav/mainwindow.cc')
-rw-r--r--miav/mainwindow.cc575
1 files changed, 575 insertions, 0 deletions
diff --git a/miav/mainwindow.cc b/miav/mainwindow.cc
new file mode 100644
index 0000000..11322b9
--- /dev/null
+++ b/miav/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 * 1.5) +
+ (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*/