Пример #1
0
/* static */ nsresult
GeckoPrintService::TranslateSettings (GtkPrintSettings *aGtkSettings,
				      GtkPageSetup *aPageSetup,
				      GtkPrinter *aPrinter,
				      const nsACString &aSourceFile,
				      PRInt16 aPrintFrames,
				      PRBool aIsForPrinting,
				      nsIPrintSettings *aSettings)
{
  NS_ENSURE_ARG (aGtkSettings);
  NS_ENSURE_ARG (aPageSetup);

  GtkPrintCapabilities capabilities = GtkPrintCapabilities (0);
  if (aIsForPrinting) {
    NS_ENSURE_TRUE (aPrinter, NS_ERROR_FAILURE);

    capabilities = gtk_printer_get_capabilities (aPrinter);
  }

  /* Initialisation */
  aSettings->SetIsInitializedFromPrinter (PR_FALSE); /* FIXME: PR_TRUE? */
  aSettings->SetIsInitializedFromPrefs (PR_FALSE); /* FIXME: PR_TRUE? */
  aSettings->SetPrintSilent (PR_FALSE);
  aSettings->SetShowPrintProgress (PR_TRUE);

  /* We always print PS to a file and then hand that off to gtk-print */
  aSettings->SetPrinterName (LITERAL ("PostScript/default"));

  if (aIsForPrinting) {
    aSettings->SetPrintToFile (PR_TRUE);

    nsString sourceFile;
    NS_CStringToUTF16 (aSourceFile,
		       NS_CSTRING_ENCODING_NATIVE_FILESYSTEM,
		       sourceFile);

    aSettings->SetToFileName (sourceFile.get ());
  } else {
    /* Otherwise mozilla will create the file nevertheless and 
     * fail since we haven't set a name!
     */
    aSettings->SetPrintToFile (PR_FALSE);
  }

  /* This is the time between printing each page, in ms.
   * It 'gives the user more time to press cancel' !
   * We don't want any of this nonsense, so set this to a low value,
   * just enough to update the print dialogue.
   */
  aSettings->SetPrintPageDelay (50);

  if (aIsForPrinting) {
#ifdef HAVE_NSIPRINTSETTINGS_SETOUTPUTFORMAT
    NS_ENSURE_TRUE (aPrinter, NS_ERROR_FAILURE);

    const char *format = gtk_print_settings_get (aGtkSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
    if (!format)
      format = "ps";

    if (strcmp (format, "pdf") == 0 &&
	gtk_printer_accepts_pdf (aPrinter)) {
      aSettings->SetOutputFormat (nsIPrintSettings::kOutputFormatPDF);
    } else if (strcmp (format, "ps") == 0 &&
	       gtk_printer_accepts_ps (aPrinter)) {
      aSettings->SetOutputFormat (nsIPrintSettings::kOutputFormatPS);
    } else {
      g_warning ("Output format '%s' specified, but printer '%s' does not support it!",
		 format, gtk_printer_get_name (aPrinter));
      return NS_ERROR_FAILURE;
    }
#endif
	  
    int n_copies = gtk_print_settings_get_n_copies (aGtkSettings);
    if (n_copies <= 0)
      return NS_ERROR_FAILURE;
    if (capabilities & GTK_PRINT_CAPABILITY_COPIES) {
      aSettings->SetNumCopies (1);
    } else {
      /* We have to copy them ourself */
      aSettings->SetNumCopies (n_copies);
      gtk_print_settings_set_n_copies (aGtkSettings, 1);
    }

    gboolean reverse = gtk_print_settings_get_reverse (aGtkSettings);
    if (capabilities & GTK_PRINT_CAPABILITY_REVERSE) {
      aSettings->SetPrintReversed (PR_FALSE);
    } else {
      aSettings->SetPrintReversed (reverse);
      gtk_print_settings_set_reverse (aGtkSettings, FALSE);
    }

    GtkPageSet pageSet = gtk_print_settings_get_page_set (aGtkSettings);
    aSettings->SetPrintOptions (nsIPrintSettings::kPrintEvenPages,
			        pageSet != GTK_PAGE_SET_ODD);
    aSettings->SetPrintOptions (nsIPrintSettings::kPrintEvenPages,
			        pageSet != GTK_PAGE_SET_EVEN);

    GtkPrintPages printPages = gtk_print_settings_get_print_pages (aGtkSettings);
    switch (printPages) {
      case GTK_PRINT_PAGES_RANGES: {
        int numRanges = 0;
        GtkPageRange *pageRanges = gtk_print_settings_get_page_ranges (aGtkSettings, &numRanges);
        if (numRanges > 0) {
          /* FIXME: We can only support one range, ignore more ranges or raise error? */
          aSettings->SetPrintRange (nsIPrintSettings::kRangeSpecifiedPageRange);
	  /* Gecko page numbers start at 1, while gtk page numbers start at 0 */
          aSettings->SetStartPageRange (pageRanges[0].start + 1);
	  aSettings->SetEndPageRange (pageRanges[0].end + 1);

	  g_free (pageRanges);
          break;
        }
	/* Fall-through to PAGES_ALL */
      }
      case GTK_PRINT_PAGES_CURRENT:
        /* not supported, fall through */
      case GTK_PRINT_PAGES_ALL:
        aSettings->SetPrintRange (nsIPrintSettings::kRangeAllPages);
        break;
        /* FIXME: we need some custom ranges here, "Selection" and "Focused Frame" */
    }
  } else {
    aSettings->SetPrintOptions (nsIPrintSettings::kPrintEvenPages, PR_TRUE);
    aSettings->SetPrintOptions (nsIPrintSettings::kPrintEvenPages, PR_TRUE);
    aSettings->SetPrintReversed (PR_FALSE);
    aSettings->SetPrintRange (nsIPrintSettings::kRangeAllPages);
  }

  /* And clear those in the settings, so the printer doesn't try to apply them too */
  gtk_print_settings_set_print_pages (aGtkSettings, GTK_PRINT_PAGES_ALL);
  gtk_print_settings_set_page_ranges (aGtkSettings, NULL, 0);
  gtk_print_settings_set_page_set (aGtkSettings, GTK_PAGE_SET_ALL);

  /* We must use the page setup here instead of the print settings, see gtk bug #485685 */
  switch (gtk_page_setup_get_orientation (aPageSetup)) {
    case GTK_PAGE_ORIENTATION_PORTRAIT:
    case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT: /* not supported */
      aSettings->SetOrientation (nsIPrintSettings::kPortraitOrientation);
      break;
    case GTK_PAGE_ORIENTATION_LANDSCAPE:
    case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE: /* not supported */
      aSettings->SetOrientation (nsIPrintSettings::kLandscapeOrientation);
      break;
  }

  aSettings->SetPrintInColor (gtk_print_settings_get_use_color (aGtkSettings));

  aSettings->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeMillimeters);

#ifdef HAVE_NSIPRINTSETTINGS_SETPAPERSIZE
  aSettings->SetPaperSize (nsIPrintSettings::kPaperSizeDefined);
#endif

  GtkPaperSize *paperSize = gtk_page_setup_get_paper_size (aPageSetup);
  if (!paperSize) {
    return NS_ERROR_FAILURE;
  }

  aSettings->SetPaperSizeType (nsIPrintSettings::kPaperSizeDefined);
  aSettings->SetPaperWidth (gtk_paper_size_get_width (paperSize, GTK_UNIT_MM));
  aSettings->SetPaperHeight (gtk_paper_size_get_height (paperSize, GTK_UNIT_MM));

#ifdef HAVE_NSIPRINTSETTINGS_SETPAPERNAME
  aSettings->SetPaperName (NS_ConvertUTF8toUTF16 (gtk_paper_size_get_name (paperSize)).get ());
#else
{
  /* Mozilla bug https://bugzilla.mozilla.org/show_bug.cgi?id=307404
   * means that we cannot actually use any paper sizes except mozilla's
   * builtin list, and we must refer to them *by name*!
  */
  static const struct {
    const char gtkPaperName[13];
    const char mozPaperName[10];
  } paperTable [] = {
    { GTK_PAPER_NAME_A5, "A5" },
    { GTK_PAPER_NAME_A4, "A4" },
    { GTK_PAPER_NAME_A3, "A3" },
    { GTK_PAPER_NAME_LETTER, "Letter" },
    { GTK_PAPER_NAME_LEGAL, "Legal" },
    { GTK_PAPER_NAME_EXECUTIVE, "Executive" },
  };

  const char *paperName = gtk_paper_size_get_name (paperSize);
	
  PRUint32 i;
  for (i = 0; i < G_N_ELEMENTS (paperTable); i++) {
    if (g_ascii_strcasecmp (paperTable[i].gtkPaperName, paperName) == 0) {
      paperName = paperTable[i].mozPaperName;
      break;
    }
  }
  if (i == G_N_ELEMENTS (paperTable)) {
    /* Not in table, fall back to A4 */
    g_warning ("Unknown paper name '%s', falling back to A4", gtk_paper_size_get_name (paperSize));
    paperName = paperTable[1].mozPaperName;
  }

  aSettings->SetPaperName (NS_ConvertUTF8toUTF16 (paperName).get ());
}
#endif /* !HAVE_NSIPRINTSETTINGS_SETPAPERNAME */

  /* Sucky mozilla wants margins in inch! */
  aSettings->SetMarginTop (gtk_page_setup_get_top_margin (aPageSetup, GTK_UNIT_INCH));
  aSettings->SetMarginBottom (gtk_page_setup_get_bottom_margin (aPageSetup, GTK_UNIT_INCH));
  aSettings->SetMarginLeft (gtk_page_setup_get_left_margin (aPageSetup, GTK_UNIT_INCH));
  aSettings->SetMarginRight (gtk_page_setup_get_right_margin (aPageSetup, GTK_UNIT_INCH));

  aSettings->SetHeaderStrLeft (eel_gconf_get_boolean (CONF_PRINT_PAGE_TITLE) ? LITERAL ("&T") : LITERAL (""));
  aSettings->SetHeaderStrCenter (LITERAL (""));
  aSettings->SetHeaderStrRight (eel_gconf_get_boolean (CONF_PRINT_PAGE_URL) ? LITERAL ("&U") : LITERAL (""));
  aSettings->SetFooterStrLeft (eel_gconf_get_boolean (CONF_PRINT_PAGE_NUMBERS) ? LITERAL ("&PT") : LITERAL (""));
  aSettings->SetFooterStrCenter (LITERAL (""));
  aSettings->SetFooterStrRight (eel_gconf_get_boolean (CONF_PRINT_DATE) ? LITERAL ("&D") : LITERAL (""));

  aSettings->SetPrintFrameType (aPrintFrames);
  aSettings->SetPrintFrameTypeUsage (nsIPrintSettings::kUseSettingWhenPossible);

  /* FIXME: only if GTK_PRINT_CAPABILITY_SCALE is not set? */
  aSettings->SetScaling (gtk_print_settings_get_scale (aGtkSettings) / 100.0);
  gtk_print_settings_set_scale (aGtkSettings, 1.0);

  aSettings->SetShrinkToFit (PR_FALSE); /* FIXME setting */
  
  aSettings->SetPrintBGColors (eel_gconf_get_boolean (CONF_PRINT_BG_COLORS) != FALSE);
  aSettings->SetPrintBGImages (eel_gconf_get_boolean (CONF_PRINT_BG_IMAGES) != FALSE);

  /* aSettings->SetPlexName (LITERAL ("default")); */
  /* aSettings->SetColorspace (LITERAL ("default")); */
  /* aSettings->SetResolutionName (LITERAL ("default")); */
  /* aSettings->SetDownloadFonts (PR_TRUE); */

  /* Unset those setting that we can handle, so they don't get applied
   * again for the print job.
   */
  /* gtk_print_settings_set_collate (aGtkSettings, FALSE); not yet */
  /* FIXME: Unset the orientation for the print job? */
  /* gtk_page_setup_set_orientation (aPageSetup, GTK_PAGE_ORIENTATION_PORTRAIT); */
  /* FIXME: unset output format -> "ps" ? */

  return NS_OK;
}
Пример #2
0
gint
yad_print_run (void)
{
  GtkWidget *dlg;
  GtkWidget *box, *img, *lbl;
  gchar *uri, *job_name = NULL;
  GtkPrintCapabilities pcap;
  GtkPrintOperationAction act = GTK_PRINT_OPERATION_ACTION_PRINT;
  gint resp, ret = 0;
  GError *err = NULL;

  /* check if file is exists */
  if (options.common_data.uri && options.common_data.uri[0])
    {
      if (!g_file_test (options.common_data.uri, G_FILE_TEST_EXISTS))
        {
          g_printerr (_("File %s not found.\n"), options.common_data.uri);
          return 1;
        }
    }
  else
    {
      g_printerr (_("Filename is not specified.\n"));
      return 1;
    }

  /* create print dialog */
  dlg = gtk_print_unix_dialog_new (options.data.dialog_title, NULL);
  gtk_window_set_type_hint (GTK_WINDOW (dlg), GDK_WINDOW_TYPE_HINT_NORMAL);
  gtk_print_unix_dialog_set_embed_page_setup (GTK_PRINT_UNIX_DIALOG (dlg), TRUE);
  pcap = GTK_PRINT_CAPABILITY_PAGE_SET | GTK_PRINT_CAPABILITY_COPIES |
    GTK_PRINT_CAPABILITY_COLLATE | GTK_PRINT_CAPABILITY_REVERSE |
    GTK_PRINT_CAPABILITY_NUMBER_UP | GTK_PRINT_CAPABILITY_NUMBER_UP_LAYOUT;
  if (options.common_data.preview && options.print_data.type != YAD_PRINT_RAW)
    pcap |= GTK_PRINT_CAPABILITY_PREVIEW;
  gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG (dlg), pcap);

  if (!settings.print_settings)
    settings.print_settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (dlg));

  uri = g_build_filename (g_get_current_dir (), "yad.pdf", NULL);
  gtk_print_settings_set (settings.print_settings, "output-uri", g_filename_to_uri (uri, NULL, NULL));
  g_free (uri);

  gtk_print_unix_dialog_set_settings (GTK_PRINT_UNIX_DIALOG (dlg), settings.print_settings);

  if (settings.page_setup)
    gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG (dlg), settings.page_setup);

  /* set window behavior */
  gtk_widget_set_name (dlg, "yad-dialog-window");
  if (options.data.sticky)
    gtk_window_stick (GTK_WINDOW (dlg));
  gtk_window_set_resizable (GTK_WINDOW (dlg), !options.data.fixed);
  gtk_window_set_keep_above (GTK_WINDOW (dlg), options.data.ontop);
  gtk_window_set_decorated (GTK_WINDOW (dlg), !options.data.undecorated);
  gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dlg), options.data.skip_taskbar);
  gtk_window_set_skip_pager_hint (GTK_WINDOW (dlg), options.data.skip_taskbar);

  /* set window size and position */
  if (!options.data.geometry)
    {
      gtk_window_set_default_size (GTK_WINDOW (dlg), options.data.width, options.data.height);
      if (options.data.center)
        gtk_window_set_position (GTK_WINDOW (dlg), GTK_WIN_POS_CENTER);
      else if (options.data.mouse)
        gtk_window_set_position (GTK_WINDOW (dlg), GTK_WIN_POS_MOUSE);
    }
  else
    {
      /* parse geometry, if given. must be after showing widget */
      gtk_widget_realize (dlg);
      gtk_window_parse_geometry (GTK_WINDOW (dlg), options.data.geometry);
    }

  /* create yad's top box */
  if (options.data.dialog_text || options.data.dialog_image)
    {
#if !GTK_CHECK_VERSION(3,0,0)
      box = gtk_hbox_new (FALSE, 0);
#else
      box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
#endif

      if (options.data.dialog_image)
        {
          GdkPixbuf *pb = NULL;

          pb = get_pixbuf (options.data.dialog_image, YAD_BIG_ICON);
          img = gtk_image_new_from_pixbuf (pb);
          if (pb)
            g_object_unref (pb);

          gtk_widget_set_name (img, "yad-dialog-image");
          gtk_box_pack_start (GTK_BOX (box), img, FALSE, FALSE, 2);
        }
      if (options.data.dialog_text)
        {
          gchar *buf = g_strcompress (options.data.dialog_text);

          lbl = gtk_label_new (NULL);
          if (!options.data.no_markup)
            gtk_label_set_markup (GTK_LABEL (lbl), buf);
          else
            gtk_label_set_text (GTK_LABEL (lbl), buf);
          gtk_widget_set_name (lbl, "yad-dialog-label");
          gtk_label_set_selectable (GTK_LABEL (lbl), options.data.selectable_labels);
          gtk_misc_set_alignment (GTK_MISC (lbl), options.data.text_align, 0.5);
          if (options.data.geometry || options.data.width != -1)
            gtk_label_set_line_wrap (GTK_LABEL (lbl), TRUE);
          gtk_box_pack_start (GTK_BOX (box), lbl, TRUE, TRUE, 2);
          g_signal_connect (G_OBJECT (lbl), "size-allocate", G_CALLBACK (size_allocate_cb), NULL);
          g_free (buf);
        }

      /* add tob box to dialog */
      gtk_widget_show_all (box);
      gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), box, TRUE, TRUE, 5);
      gtk_box_reorder_child (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), box, 0);
    }

  do
    {
      resp = gtk_dialog_run (GTK_DIALOG (dlg));
      switch (resp)
        {
        case GTK_RESPONSE_APPLY:   /* ask for preview */
          act = GTK_PRINT_OPERATION_ACTION_PREVIEW;
        case GTK_RESPONSE_OK:      /* run print */
          settings.print_settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (dlg));
          settings.page_setup = gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG (dlg));
          job_name = g_strdup_printf ("yad-%s-%d", g_path_get_basename (options.common_data.uri), getpid ());
          if (options.print_data.type != YAD_PRINT_RAW)
            {
              /* print text or image */
              GtkPrintOperation *op = gtk_print_operation_new ();
              gtk_print_operation_set_unit (op, GTK_UNIT_POINTS);
              gtk_print_operation_set_print_settings (op, settings.print_settings);
              gtk_print_operation_set_default_page_setup (op, settings.page_setup);
              gtk_print_operation_set_job_name (op, job_name);

              switch (options.print_data.type)
                {
                case YAD_PRINT_TEXT:
                  g_signal_connect (G_OBJECT (op), "begin-print", G_CALLBACK (begin_print_text), NULL);
                  g_signal_connect (G_OBJECT (op), "draw-page", G_CALLBACK (draw_page_text), NULL);
                  break;
                case YAD_PRINT_IMAGE:
                  gtk_print_operation_set_n_pages (op, 1);
                  g_signal_connect (G_OBJECT (op), "draw-page", G_CALLBACK (draw_page_image), NULL);
                  break;
                default:;
                }

              if (gtk_print_operation_run (op, act, NULL, &err) == GTK_PRINT_OPERATION_RESULT_ERROR)
                {
                  g_printerr (_("Printing failed: %s\n"), err->message);
                  ret = 1;
                }
            }
          else
            {
              /* print raw ps or pdf data */
              GtkPrinter *prnt;
              GtkPrintJob *job;

              prnt = gtk_print_unix_dialog_get_selected_printer (GTK_PRINT_UNIX_DIALOG (dlg));

              if (g_str_has_suffix (options.common_data.uri, ".ps"))
                {
                  if (!gtk_printer_accepts_ps (prnt))
                    {
                      g_printerr (_("Printer doesn't support ps format.\n"));
                      ret = 1;
                    }
                }
              else if (g_str_has_suffix (options.common_data.uri, ".pdf"))
                {
                  if (!gtk_printer_accepts_pdf (prnt))
                    {
                      g_printerr (_("Printer doesn't support pdf format.\n"));
                      ret = 1;
                    }
                }
              else
                {
                  g_printerr (_("This file type is not supported for raw printing.\n"));
                  ret = 1;
                }
              if (ret == 1)
                break;

              job = gtk_print_job_new (job_name, prnt, settings.print_settings, settings.page_setup);
              if (gtk_print_job_set_source_file (job, options.common_data.uri, &err))
                {
                  gtk_print_job_send (job, (GtkPrintJobCompleteFunc) raw_print_done, &ret, NULL);
                  gtk_main ();
                }
              else
                {
                  g_printerr (_("Load source file failed: %s\n"), err->message);
                  ret = 1;
                }
            }
          break;
        default:
          ret = 1;
          break;
        }
    }
  while (resp == GTK_RESPONSE_APPLY);

  gtk_widget_destroy (dlg);
  write_settings ();
  return ret;
}
Пример #3
0
NS_IMETHODIMP nsDeviceContextSpecGTK::GetSurfaceForPrinter(gfxASurface **aSurface)
{
  *aSurface = nsnull;

  const char *path;
  GetPath(&path);

  double width, height;
  mPrintSettings->GetEffectivePageSize(&width, &height);

  // If we're in landscape mode, we'll be rotating the output --
  // need to swap width & height.
  PRInt32 orientation;
  mPrintSettings->GetOrientation(&orientation);
  if (nsIPrintSettings::kLandscapeOrientation == orientation) {
    double tmp = width;
    width = height;
    height = tmp;
  }

  // convert twips to points
  width  /= TWIPS_PER_POINT_FLOAT;
  height /= TWIPS_PER_POINT_FLOAT;

  DO_PR_DEBUG_LOG(("\"%s\", %f, %f\n", path, width, height));
  nsresult rv;

  // Spool file. Use Glib's temporary file function since we're
  // already dependent on the gtk software stack.
  gchar *buf;
  gint fd = g_file_open_tmp("XXXXXX.tmp", &buf, nsnull);
  if (-1 == fd)
    return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
  close(fd);

  rv = NS_NewNativeLocalFile(nsDependentCString(buf), PR_FALSE,
                             getter_AddRefs(mSpoolFile));
  if (NS_FAILED(rv)) {
    unlink(buf);
    return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
  }

  mSpoolName = buf;
  g_free(buf);

  mSpoolFile->SetPermissions(0600);

  nsCOMPtr<nsIFileOutputStream> stream = do_CreateInstance("@mozilla.org/network/file-output-stream;1");
  rv = stream->Init(mSpoolFile, -1, -1, 0);
  if (NS_FAILED(rv))
    return rv;

  PRInt16 format;
  mPrintSettings->GetOutputFormat(&format);

  nsRefPtr<gfxASurface> surface;
  gfxSize surfaceSize(width, height);

  // Determine the real format with some GTK magic
  if (format == nsIPrintSettings::kOutputFormatNative) {
    if (mIsPPreview) {
      // There is nothing to detect on Print Preview, use PS.
      format = nsIPrintSettings::kOutputFormatPS;
    } else {
      const gchar* fmtGTK = gtk_print_settings_get(mGtkPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
      if (!fmtGTK && GTK_IS_PRINTER(mGtkPrinter)) {
        // Likely not print-to-file, check printer's capabilities
        format = (gtk_printer_accepts_ps(mGtkPrinter)) ? nsIPrintSettings::kOutputFormatPS
                                                       : nsIPrintSettings::kOutputFormatPDF;
      } else if (nsDependentCString(fmtGTK).EqualsIgnoreCase("pdf")) {
          format = nsIPrintSettings::kOutputFormatPDF;
      } else {
          format = nsIPrintSettings::kOutputFormatPS;
      }
    }
  }

  if (format == nsIPrintSettings::kOutputFormatPDF) {
    surface = new gfxPDFSurface(stream, surfaceSize);
  } else {
    surface = new gfxPSSurface(stream, surfaceSize);
  }

  if (!surface)
    return NS_ERROR_OUT_OF_MEMORY;

  surface.swap(*aSurface);

  return NS_OK;
}