void LVRMainWindow::connectSignalsAndSlots()
{
    QObject::connect(m_actionOpen, SIGNAL(activated()), this, SLOT(loadModel()));
    QObject::connect(m_actionExport, SIGNAL(activated()), this, SLOT(exportSelectedModel()));
    QObject::connect(treeWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showTreeContextMenu(const QPoint&)));
    QObject::connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(restoreSliders(QTreeWidgetItem*, int)));
    QObject::connect(treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(setModelVisibility(QTreeWidgetItem*, int)));

    QObject::connect(m_actionQuit, SIGNAL(activated()), qApp, SLOT(quit()));

    QObject::connect(m_actionShowColorDialog, SIGNAL(activated()), this, SLOT(showColorDialog()));
    QObject::connect(m_actionRenameModelItem, SIGNAL(activated()), this, SLOT(renameModelItem()));
    QObject::connect(m_actionDeleteModelItem, SIGNAL(activated()), this, SLOT(deleteModelItem()));
    QObject::connect(m_actionExportModelTransformed, SIGNAL(activated()), this, SLOT(exportSelectedModel()));

    QObject::connect(m_actionReset_Camera, SIGNAL(activated()), this, SLOT(updateView()));
    QObject::connect(m_actionStore_Current_View, SIGNAL(activated()), this, SLOT(saveCamera()));
    QObject::connect(m_actionRecall_Stored_View, SIGNAL(activated()), this, SLOT(loadCamera()));
    QObject::connect(m_actionCameraPathTool, SIGNAL(activated()), this, SLOT(openCameraPathTool()));

    QObject::connect(m_actionEstimate_Normals, SIGNAL(activated()), this, SLOT(estimateNormals()));
    QObject::connect(m_actionMarching_Cubes, SIGNAL(activated()), this, SLOT(reconstructUsingMarchingCubes()));
    QObject::connect(m_actionPlanar_Marching_Cubes, SIGNAL(activated()), this, SLOT(reconstructUsingPlanarMarchingCubes()));
    QObject::connect(m_actionExtended_Marching_Cubes, SIGNAL(activated()), this, SLOT(reconstructUsingExtendedMarchingCubes()));

    QObject::connect(m_actionPlanar_Optimization, SIGNAL(activated()), this, SLOT(optimizePlanes()));
    QObject::connect(m_actionRemove_Artifacts, SIGNAL(activated()), this, SLOT(removeArtifacts()));

    QObject::connect(m_actionRemove_Outliers, SIGNAL(activated()), this, SLOT(removeOutliers()));
    QObject::connect(m_actionMLS_Projection, SIGNAL(activated()), this, SLOT(applyMLSProjection()));

    QObject::connect(m_actionICP_Using_Manual_Correspondance, SIGNAL(activated()), this, SLOT(manualICP()));

    QObject::connect(m_menuAbout, SIGNAL(triggered(QAction*)), this, SLOT(showAboutDialog(QAction*)));

    QObject::connect(m_correspondanceDialog->m_dialog, SIGNAL(accepted()), m_pickingInteractor, SLOT(correspondenceSearchOff()));
    QObject::connect(m_correspondanceDialog->m_dialog, SIGNAL(accepted()), this, SLOT(alignPointClouds()));
    QObject::connect(m_correspondanceDialog->m_dialog, SIGNAL(rejected()), m_pickingInteractor, SLOT(correspondenceSearchOff()));
    QObject::connect(m_correspondanceDialog, SIGNAL(addArrow(LVRVtkArrow*)), this, SLOT(addArrow(LVRVtkArrow*)));
    QObject::connect(m_correspondanceDialog, SIGNAL(removeArrow(LVRVtkArrow*)), this, SLOT(removeArrow(LVRVtkArrow*)));
    QObject::connect(m_correspondanceDialog, SIGNAL(disableCorrespondenceSearch()), m_pickingInteractor, SLOT(correspondenceSearchOff()));
    QObject::connect(m_correspondanceDialog, SIGNAL(enableCorrespondenceSearch()), m_pickingInteractor, SLOT(correspondenceSearchOn()));

    QObject::connect(m_actionShow_Points, SIGNAL(toggled(bool)), this, SLOT(togglePoints(bool)));
    QObject::connect(m_actionShow_Normals, SIGNAL(toggled(bool)), this, SLOT(toggleNormals(bool)));
    QObject::connect(m_actionShow_Mesh, SIGNAL(toggled(bool)), this, SLOT(toggleMeshes(bool)));
    QObject::connect(m_actionShow_Wireframe, SIGNAL(toggled(bool)), this, SLOT(toggleWireframe(bool)));
    QObject::connect(m_actionShowBackgroundSettings, SIGNAL(activated()), this, SLOT(showBackgroundDialog()));

    QObject::connect(m_horizontalSliderPointSize, SIGNAL(valueChanged(int)), this, SLOT(changePointSize(int)));
    QObject::connect(m_horizontalSliderTransparency, SIGNAL(valueChanged(int)), this, SLOT(changeTransparency(int)));

    QObject::connect(m_comboBoxShading, SIGNAL(currentIndexChanged(int)), this, SLOT(changeShading(int)));

    QObject::connect(m_buttonCameraPathTool, SIGNAL(pressed()), this, SLOT(openCameraPathTool()));
    QObject::connect(m_buttonCreateMesh, SIGNAL(pressed()), this, SLOT(reconstructUsingMarchingCubes()));
    QObject::connect(m_buttonExportData, SIGNAL(pressed()), this, SLOT(exportSelectedModel()));
    QObject::connect(m_buttonTransformModel, SIGNAL(pressed()), this, SLOT(showTransformationDialog()));

    QObject::connect(m_pickingInteractor, SIGNAL(firstPointPicked(double*)),m_correspondanceDialog, SLOT(firstPointPicked(double*)));
    QObject::connect(m_pickingInteractor, SIGNAL(secondPointPicked(double*)),m_correspondanceDialog, SLOT(secondPointPicked(double*)));

    QObject::connect(this, SIGNAL(correspondenceDialogOpened()), m_pickingInteractor, SLOT(correspondenceSearchOn()));
}
void editModel()
{
  int width = 65, height = 22, i, j;            /***** ncurses related variables */
  WINDOW *editscr = popupWindow(width, height);

  int top = 0, current = 0;  /***** menu selection related variables */
  int max_view = 10;

  int request_finish = 0;    /***** request_finish = 1 breaks the main while loop */

  while (!request_finish)
  {
    wattrset (editscr, color_term ? COLOR_PAIR(2) | A_BOLD : A_NORMAL); /***** set bg color of the dialog */

    /*****
     * draw a box around the dialog window
     * and empty it.
     *****/
    werase (editscr);
    box (editscr, 0, 0);
    for (i = 1; i < width-1; i++)
      for (j = 1; j < height-1; j++)
	mvwaddch(editscr, j, i, ' ');

    /***** dialog header */

    mvwaddstr(editscr, 1, 2, "Edit Speaker Model");
    mvwaddseparator(editscr, 2, width);

    /***** display help at the bottom */

    mvwaddseparator(editscr, height-4, width);
    mvwaddstr(editscr, height-3, 2, "a = add item, d = delete item, Enter = edit item");
    mvwaddstr(editscr, height-2, 2, "b = back to main menu");

    /***** display information about current speaker model in a table */

    mvwaddstr(editscr, 4, 2, "Number of items:");
    mvwaddint(editscr, 4, 19, model->number_of_items);

    mvwaddstr(editscr, 6, 4, "Label");
    mvwaddch(editscr,  6,25, ACS_VLINE);
    mvwaddstr(editscr, 6,27, "Command");
    mvwaddch(editscr,  6,48, ACS_VLINE);
    mvwaddstr(editscr, 6,50, "Samples");

    /***** display table */

    for (i = 0; i < 55; i++)
      mvwaddch(editscr, 7, 3+i, ACS_HLINE);
    mvwaddch(editscr,  7,25, ACS_PLUS);
    mvwaddch(editscr,  7,48, ACS_PLUS);
    for (i = 0; i < max_view; i++)
    {
      mvwaddch(editscr,  8+i, 25, ACS_VLINE);
      mvwaddch(editscr,  8+i, 48, ACS_VLINE);
    }

    /***** fill table */

    for (i = 0; i < MIN2(model->number_of_items, max_view); i++)
    {
      setHighlight(editscr, active, i == current);
      mvwaddstr(editscr, 8+i,  3, "                      ");
      mvwaddstr(editscr, 8+i, 26, "                      ");
      mvwaddstr(editscr, 8+i, 49, "         ");
      mvwaddnstr(editscr, 8+i,  4, getModelItem(model, top+i)->label, 20);
      mvwaddnstr(editscr, 8+i, 27, getModelItem(model, top+i)->command, 20);
      mvwaddint(editscr, 8+i, 53, getModelItem(model, top+i)->number_of_samples);
    }
    wattroff(editscr, A_REVERSE);

    /***** up/down arrows indicate that not all items can be displayed */

    if (top > 0)
    {
      mvwaddch(editscr, 8, 2, ACS_UARROW);
      mvwaddch(editscr, 8+1, 2, ACS_VLINE);
    }
    if (model->number_of_items > max_view && top+max_view <= model->number_of_items-1)
    {
      mvwaddch(editscr, 8+max_view-2, 2, ACS_VLINE);
      mvwaddch(editscr, 8+max_view-1, 2, ACS_DARROW);
    }

    wmove(editscr, 1,21); /***** move cursor to an appropriate location */
    wrefresh(editscr);    /***** refresh dialog window */

    /* process the command keystroke */

    switch(getch())
    {
    case KEY_UP: /***** cursor up */
      if (top+current > 0)
      {
	if (current > 0)
	 current--;
	else
	  top--;
      }
      break;
    case KEY_DOWN: /***** cursor down */
      if (top+current < model->number_of_items-1)
      {
	if (current < max_view-1)
	 current++;
	else
	  top++;
      }
      break;
    case 'b':
      /*****
       * allow leaving of the menu only if a predefined minimum amount of
       * sample utterances has been donated for each model item
       *****/
      j = MIN_NR_SAMPLES_PER_ITEM;
      for (i = 0; i < model->number_of_items; i++)
	if (getModelItem(model, i)->number_of_samples < j)
	{
	  j = 0;
	  break;
	}
      if (j < MIN_NR_SAMPLES_PER_ITEM) /***** at least one model item doesn't meet requirements */
      {
	int width = 42, height = 10, i, j;             /***** ncurses related variables */
	WINDOW *warnscr = popupWindow (width, height);

	char tmp_string[80];

	wattrset (warnscr, color_term ? COLOR_PAIR(2) | A_BOLD : A_NORMAL); /***** set bg color of the dialog */

	/*****
	 * draw a box around the dialog window
	 * and empty it.
	 *****/
	werase (warnscr);
	box (warnscr, 0, 0);
	for (i = 1; i < width-1; i++)
	  for (j = 1; j < height-1; j++)
	    mvwaddch(warnscr, j, i, ' ');

	/***** dialog header */
	
	mvwaddstr(warnscr, 1, 2, "Warning!");
	mvwaddseparator(warnscr, 2, width);

	/***** dialog message */
	
	sprintf(tmp_string, "We need at least %d sample utterances", MIN_NR_SAMPLES_PER_ITEM);
	mvwaddstr(warnscr, 3, 2, tmp_string);
	mvwaddstr(warnscr, 4, 2,"for each speaker model item!!!");
	mvwaddstr(warnscr, 5, 2,"Please donate the minimum number of ");
	mvwaddstr(warnscr, 6, 2,"samples before leaving this menu!");
	mvwaddstrcntr(warnscr, 8, width, "Press any key to continue ...");
	
	wmove(warnscr, 1, 11); /***** move cursor to an appropriate location */
	wrefresh (warnscr);    /***** refresh dialog window */
	
	getch();           /***** wait for keyboard input */
	delwin(warnscr);   /***** delete ncurses dialog window */
      }
      else
	request_finish = 1; /***** otherwise prepare to leave menu */
      break;
    case ENTER: /***** edit the currently selected model item */
      if (model->number_of_items > 0)
	editModelItem(getModelItem(model, top+current));
      break;
    case 'a':   /***** append a new item to the speaker model */
      appendEmptyModelItem(model, "New Item", "New Command");
      modified = 1; /***** switch 'modified' to 1 */

      /***** set cursor to show new item */

      current = model->number_of_items-1 - top;
      while (current > max_view-1)
      {
	current--;
	top++;
      }
      break;
    case 'd':    /***** delete currently selected item from model */
      deleteModelItem(model, top+current);
      modified = 1; /***** switch 'modified' to 1 */

      /***** set cursor to a valid value */

      if (top+current == model->number_of_items)
      {
	if (top > 0)
	  top--;
	else if (current > 0)
	  current--;
      }
      break;
    }
  }
}