diff --git a/src/apps/screenshot/Jamfile b/src/apps/screenshot/Jamfile index 366ed6cb1e..aec73e75d7 100644 --- a/src/apps/screenshot/Jamfile +++ b/src/apps/screenshot/Jamfile @@ -1,15 +1,14 @@ SubDir HAIKU_TOP src apps screenshot ; -UseLibraryHeaders png zlib ; +UseLibraryHeaders zlib ; UsePrivateHeaders interface ; Application Screenshot : main.cpp - PNGDump.cpp PreviewView.cpp Screenshot.cpp ScreenshotWindow.cpp - : be tracker translation libpng.so libz.so $(TARGET_LIBSUPC++) + : be tracker translation libz.so $(TARGET_LIBSUPC++) : Screenshot.rdef ; diff --git a/src/apps/screenshot/PNGDump.cpp b/src/apps/screenshot/PNGDump.cpp deleted file mode 100644 index 4acf24c26d..0000000000 --- a/src/apps/screenshot/PNGDump.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright 2001-2006, Haiku. - * Distributed under the terms of the MIT License. - * - * Authors: - * DarkWyrm - * Stephan Aßmus - */ - -/** Function for saving a generic framebuffer to a PNG file */ - -#include "PNGDump.h" - -#include -#include -#include - -#include - -#include -#include -#include -#include - - -#define TRACE_PNGDUMP -#ifdef TRACE_PNGDUMP -# define TRACE(x) printf x -#else -# define TRACE(x) ; -#endif - - -status_t -SaveToPNG(const char* filename, const BRect& bounds, color_space space, - const void* bits, int32 bitsLength, int32 bytesPerRow) -{ - int32 width = bounds.IntegerWidth() + 1; - int32 height = bounds.IntegerHeight() + 1; - - TRACE(("SaveToPNG: %s (%ldx%ld)\n", filename, width, height)); - - FILE *file = fopen(filename, "wb"); - if (file == NULL) { - TRACE(("Couldn't open file: %s\n", strerror(errno))); - return errno; - } - - png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, - NULL, NULL, NULL); - if (png == NULL) { - TRACE(("Couldn't create write struct\n")); - fclose(file); - return B_NO_MEMORY; - } - - png_infop info = png_create_info_struct(png); - if (info == NULL) { - TRACE(("Couldn't create info struct\n")); - png_destroy_write_struct(&png, NULL); - fclose(file); - return B_NO_MEMORY; - } - - if (setjmp(png->jmpbuf)) { - png_destroy_write_struct(&png, NULL); - fclose(file); - return B_ERROR; - } - - png_init_io(png, file); - png_set_bgr(png); - - // TODO: support other color spaces if needed - - switch (space) { - case B_RGB32: - case B_RGBA32: - { - // create file without alpha channel - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGB, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png, info); - - // convert from 32 bit RGB to 24 bit RGB while saving - png_byte* src = (png_byte*)bits; - int srcRowBytes = width * 4; - int dstRowBytes = width * 3; - int srcRowOffset = bytesPerRow - srcRowBytes; - png_byte tempRow[dstRowBytes]; - for (int row = 0; row < height; row++) { - for (int i = 0; i < dstRowBytes; i += 3, src += 4) { - tempRow[i] = src[0]; - tempRow[i + 1] = src[1]; - tempRow[i + 2] = src[2]; - } - src += srcRowOffset; - png_write_row(png, tempRow); - } - break; - } - - case B_RGB16: - { - // create file without alpha channel - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGB, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png, info); - - // convert from 16 bit RGB to 24 bit RGB while saving - uint16* src = (uint16 *)bits; - int dstRowBytes = width * 3; - png_byte tempRow[dstRowBytes]; - for (int row = 0; row < height; row++) { - for (int i = 0; i < dstRowBytes; i += 3, src++) { - tempRow[i + 2] = (*src & 0xf800) >> 8; - tempRow[i + 1] = (*src & 0x07e0) >> 3; - tempRow[i] = (*src & 0x001f) << 3; - } - src = (uint16 *)((uint8 *)bits + row * bytesPerRow); - png_write_row(png, tempRow); - } - break; - } - - case B_RGB15: - { - // create file without alpha channel - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGB, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png, info); - - // convert from 15 bit RGB to 24 bit RGB while saving - uint16* src = (uint16 *)bits; - int dstRowBytes = width * 3; - png_byte tempRow[dstRowBytes]; - for (int row = 0; row < height; row++) { - for (int i = 0; i < dstRowBytes; i += 3, src++) { - tempRow[i + 2] = (*src & 0x7c00) >> 7; - tempRow[i + 1] = (*src & 0x03e0) >> 2; - tempRow[i] = (*src & 0x001f) << 3; - } - src = (uint16 *)((uint8 *)bits + row * bytesPerRow); - png_write_row(png, tempRow); - } - break; - } - - case B_CMAP8: - { - // create file without alpha channel - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGB, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png, info); - - // convert from 8 bit CMAP to 24 bit RGB while saving - const color_map *colorMap = system_colors(); - uint8* src = (uint8 *)bits; - int dstRowBytes = width * 3; - png_byte tempRow[dstRowBytes]; - for (int row = 0; row < height; row++) { - for (int i = 0; i < dstRowBytes; i += 3, src++) { - tempRow[i + 2] = colorMap->color_list[*src].red; - tempRow[i + 1] = colorMap->color_list[*src].green; - tempRow[i] = colorMap->color_list[*src].blue; - } - src = (uint8 *)bits + row * bytesPerRow; - png_write_row(png, tempRow); - } - break; - } - - default: - { - TRACE(("Unsupported color space %x\n", space)); - png_destroy_write_struct(&png, NULL); - fclose(file); - return B_ERROR; - } - } - - png_write_end(png, info); - png_destroy_write_struct(&png, NULL); - - fclose(file); - - // Set the file type manually, so that it doesn't have to be - // picked up by the registrar or Tracker, first - BNode node(filename); - BNodeInfo nodeInfo(&node); - if (nodeInfo.InitCheck() == B_OK) - nodeInfo.SetType("image/png"); - - return B_OK; -} diff --git a/src/apps/screenshot/PNGDump.h b/src/apps/screenshot/PNGDump.h deleted file mode 100644 index 6c4b2f4fd7..0000000000 --- a/src/apps/screenshot/PNGDump.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2001-2005, Haiku. - * Distributed under the terms of the MIT License. - * - * Authors: - * DarkWyrm - */ -#ifndef PNGDUMP_H -#define PNGDUMP_H - - -#include - -class BRect; - - -status_t SaveToPNG(const char* filename, const BRect& bounds, color_space space, - const void* bits, int32 bitsLength, int32 bytesPerRow); - -#endif diff --git a/src/apps/screenshot/PreviewView.cpp b/src/apps/screenshot/PreviewView.cpp index 59a4201410..8bedac23df 100644 --- a/src/apps/screenshot/PreviewView.cpp +++ b/src/apps/screenshot/PreviewView.cpp @@ -4,11 +4,14 @@ */ #include "PreviewView.h" + + #include PreviewView::PreviewView() - : BView("preview", B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE) + : + BView("preview", B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE) { } @@ -22,6 +25,6 @@ void PreviewView::Draw(BRect updateRect) { BRect rect = Frame(); - be_control_look->DrawTextControlBorder(this, rect, rect, + be_control_look->DrawTextControlBorder(this, rect, rect, ui_color(B_PANEL_BACKGROUND_COLOR)); } diff --git a/src/apps/screenshot/PreviewView.h b/src/apps/screenshot/PreviewView.h index 0a922c72d7..de34d089be 100644 --- a/src/apps/screenshot/PreviewView.h +++ b/src/apps/screenshot/PreviewView.h @@ -2,7 +2,6 @@ * Copyright 2009, Philippe Saint-Pierre, stpere@gmail.com * Distributed under the terms of the MIT License. */ - #ifndef PREVIEW_VIEW_H #define PREVIEW_VIEW_H diff --git a/src/apps/screenshot/Screenshot.cpp b/src/apps/screenshot/Screenshot.cpp index a5870d5f45..f296dec44a 100644 --- a/src/apps/screenshot/Screenshot.cpp +++ b/src/apps/screenshot/Screenshot.cpp @@ -1,10 +1,14 @@ /* * Copyright Karsten Heimrich, host.haiku@gmx.de. All rights reserved. * Distributed under the terms of the MIT License. + * + * Authors: + * Karsten Heimrich + * Fredrik Modéen */ + #include "Screenshot.h" -#include "ScreenshotWindow.h" #include @@ -12,10 +16,19 @@ #include +#include + + +#include "ScreenshotWindow.h" + + Screenshot::Screenshot() - : BApplication("application/x-vnd.Haiku-Screenshot"), + : + BApplication("application/x-vnd.Haiku-Screenshot"), fArgvReceived(false), - fRefsReceived(false) + fRefsReceived(false), + fImageFileType(B_PNG_FORMAT), + fTranslator(8) { } @@ -28,7 +41,7 @@ Screenshot::~Screenshot() void Screenshot::ReadyToRun() { - if(!fArgvReceived && !fRefsReceived) + if (!fArgvReceived && !fRefsReceived) new ScreenshotWindow(); fArgvReceived = false; @@ -56,7 +69,7 @@ Screenshot::RefsReceived(BMessage* message) bool showConfigureWindow = false; message->FindBool("configure", &showConfigureWindow); - + new ScreenshotWindow(delay * 1000000, includeBorder, includeMouse, grabActiveWindow, showConfigureWindow, saveScreenshotSilent); @@ -78,17 +91,26 @@ Screenshot::ArgvReceived(int32 argc, char** argv) for (int32 i = 0; i < argc; i++) { if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) _ShowHelp(); - else if (strcmp(argv[i], "-b") == 0 || strcmp(argv[i], "--border") == 0) + else if (strcmp(argv[i], "-b") == 0 + || strcmp(argv[i], "--border") == 0) includeBorder = true; - else if (strcmp(argv[i], "-m") == 0 || strcmp(argv[i], "--mouse-pointer") == 0) + else if (strcmp(argv[i], "-m") == 0 + || strcmp(argv[i], "--mouse-pointer") == 0) includeMouse = true; - else if (strcmp(argv[i], "-w") == 0 || strcmp(argv[i], "--window") == 0) + else if (strcmp(argv[i], "-w") == 0 + || strcmp(argv[i], "--window") == 0) grabActiveWindow = true; - else if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--silent") == 0) + else if (strcmp(argv[i], "-s") == 0 + || strcmp(argv[i], "--silent") == 0) saveScreenshotSilent = true; - else if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--options") == 0) + else if (strcmp(argv[i], "-o") == 0 + || strcmp(argv[i], "--options") == 0) showConfigureWindow = true; - else if (strcmp(argv[i], "-d") == 0 + else if (strcmp(argv[i], "-f") == 0 + || strncmp(argv[i], "--format", 6) == 0 + || strncmp(argv[i], "--format=", 7) == 0) { + _SetImageTypeSilence(argv[i + 1]); + } else if (strcmp(argv[i], "-d") == 0 || strncmp(argv[i], "--delay", 7) == 0 || strncmp(argv[i], "--delay=", 8) == 0) { int32 seconds = -1; @@ -97,16 +119,19 @@ Screenshot::ArgvReceived(int32 argc, char** argv) if (seconds >= 0) { delay = seconds * 1000000; i++; - } - else { - printf("Screenshot: option requires an argument -- %s\n", argv[i]); + } else { + printf("Screenshot: option requires an argument -- %s\n" + , argv[i]); exit(0); } } } + fArgvReceived = true; - new ScreenshotWindow(delay, includeBorder, includeMouse, grabActiveWindow, - showConfigureWindow, saveScreenshotSilent); + + new ScreenshotWindow(delay, includeBorder, includeMouse, grabActiveWindow, + showConfigureWindow, saveScreenshotSilent, fImageFileType, + fTranslator); } @@ -121,9 +146,38 @@ Screenshot::_ShowHelp() const printf(" -w, --window Capture the active window instead of the entire screen\n"); printf(" -d, --delay=seconds Take screenshot after specified delay [in seconds]\n"); printf(" -s, --silent Saves the screenshot without showing the app window\n"); - printf(" overrides --options, saves to home folder as png\n"); + printf(" overrides --options\n"); + printf(" -f, --format=image Write the image format you like to save as\n"); + printf(" [bmp], [gif], [jpg], [png], [ppm], [targa], [tiff]\n"); printf("\n"); printf("Note: OPTION -b, --border takes only effect when used with -w, --window\n"); - exit(0); } + + +void +Screenshot::_SetImageTypeSilence(const char* name) +{ + if (strcmp(name, "bmp") == 0) { + fImageFileType = B_BMP_FORMAT; + fTranslator = 1; + } else if (strcmp(name, "gif") == 0) { + fImageFileType = B_GIF_FORMAT; + fTranslator = 3; + } else if (strcmp(name, "jpg") == 0) { + fImageFileType = B_JPEG_FORMAT; + fTranslator = 6; + } else if (strcmp(name, "ppm") == 0) { + fImageFileType = B_PPM_FORMAT; + fTranslator = 9; + } else if (strcmp(name, "targa") == 0) { + fImageFileType = B_TGA_FORMAT; + fTranslator = 14; + } else if (strcmp(name, "tif") == 0) { + fImageFileType = B_TIFF_FORMAT; + fTranslator = 15; + } else { //png + fImageFileType = B_PNG_FORMAT; + fTranslator = 8; + } +} diff --git a/src/apps/screenshot/Screenshot.h b/src/apps/screenshot/Screenshot.h index 4c8c24fa99..a24b4b8d2d 100644 --- a/src/apps/screenshot/Screenshot.h +++ b/src/apps/screenshot/Screenshot.h @@ -1,7 +1,15 @@ /* * Copyright Karsten Heimrich, host.haiku@gmx.de. All rights reserved. * Distributed under the terms of the MIT License. + * + * Authors: + * Karsten Heimrich + * Fredrik Modéen */ +#ifndef SCREENSHOT_H +#define SCREENSHOT_H + + #include @@ -16,8 +24,12 @@ public: private: void _ShowHelp() const; + void _SetImageTypeSilence(const char* name); -private: bool fArgvReceived; bool fRefsReceived; + int32 fImageFileType; + int32 fTranslator; }; + +#endif /* SCREENSHOT_H */ diff --git a/src/apps/screenshot/ScreenshotWindow.cpp b/src/apps/screenshot/ScreenshotWindow.cpp index d4f1a200d5..9da3232dc7 100644 --- a/src/apps/screenshot/ScreenshotWindow.cpp +++ b/src/apps/screenshot/ScreenshotWindow.cpp @@ -1,11 +1,18 @@ /* * Copyright Karsten Heimrich, host.haiku@gmx.de. All rights reserved. * Distributed under the terms of the MIT License. + * + * Authors: + * Karsten Heimrich + * Fredrik Modéen */ #include "ScreenshotWindow.h" -#include "PNGDump.h" + +#include +#include + #include #include @@ -44,8 +51,7 @@ #include -#include -#include +#include "PreviewView.h" enum { @@ -81,8 +87,9 @@ public: ScreenshotWindow::ScreenshotWindow(bigtime_t delay, bool includeBorder, bool includeMouse, bool grabActiveWindow, bool showConfigWindow, - bool saveScreenshotSilent) - : BWindow(BRect(0, 0, 200.0, 100.0), "Take Screenshot", B_TITLED_WINDOW, + bool saveScreenshotSilent, int32 imageFileType, int32 translator) + : + BWindow(BRect(0, 0, 200.0, 100.0), "Take Screenshot", B_TITLED_WINDOW, B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_QUIT_ON_WINDOW_CLOSE | B_AVOID_FRONT | B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), fDelayControl(NULL), @@ -95,15 +102,19 @@ ScreenshotWindow::ScreenshotWindow(bigtime_t delay, bool includeBorder, fIncludeMouse(includeMouse), fGrabActiveWindow(grabActiveWindow), fShowConfigWindow(showConfigWindow), - fExtension("") + fSaveScreenshotSilent(saveScreenshotSilent), + fExtension(""), + fTranslator(translator), + fImageFileType(imageFileType) { - if (saveScreenshotSilent) { + if (fSaveScreenshotSilent) { _TakeScreenshot(); - _SaveScreenshotSilent(); + _SaveScreenshot(); be_app_messenger.SendMessage(B_QUIT_REQUESTED); } else { _InitWindow(); - _CenterAndShow(); + CenterOnScreen(); + Show(); } } @@ -121,53 +132,58 @@ ScreenshotWindow::~ScreenshotWindow() void ScreenshotWindow::MessageReceived(BMessage* message) { +// message->PrintToStream(); switch (message->what) { - case kScreenshotType: { + case kScreenshotType: fGrabActiveWindow = false; if (fActiveWindow->Value() == B_CONTROL_ON) fGrabActiveWindow = true; fWindowBorder->SetEnabled(fGrabActiveWindow); - } break; + break; - case kIncludeBorder: { - fIncludeBorder = (fWindowBorder->Value() == B_CONTROL_ON); - } break; + case kIncludeBorder: + fIncludeBorder = (fWindowBorder->Value() == B_CONTROL_ON); + break; - case kShowMouse: { + case kShowMouse: + printf("kShowMouse\n"); fIncludeMouse = (fShowMouse->Value() == B_CONTROL_ON); - } break; + break; - case kBackToSave: { + case kBackToSave: + { BCardLayout* layout = dynamic_cast (GetLayout()); if (layout) layout->SetVisibleItem(1L); SetTitle("Save Screenshot"); - } break; + break; + } - case kTakeScreenshot: { + case kTakeScreenshot: Hide(); _TakeScreenshot(); _UpdatePreviewPanel(); Show(); - } break; - - case kImageOutputFormat: { + break; + + case kImageOutputFormat: message->FindInt32("be:type", &fImageFileType); message->FindInt32("be:translator", &fTranslator); - const char* text = fNameControl->Text(); - fNameControl->SetText(_FindValidFileName(text).String()); - } break; - - case kLocationChanged: { + fNameControl->SetText(_FindValidFileName(fNameControl->Text())); + break; + + case kLocationChanged: + { void* source = NULL; if (message->FindPointer("source", &source) == B_OK) fLastSelectedPath = static_cast (source); - const char* text = fNameControl->Text(); - fNameControl->SetText(_FindValidFileName(text).String()); - } break; - - case kChooseLocation: { + fNameControl->SetText(_FindValidFileName(fNameControl->Text())); + break; + } + + case kChooseLocation: + { if (!fOutputPathPanel) { BMessenger target(this); fOutputPathPanel = new BFilePanel(B_OPEN_PANEL, &target, @@ -176,26 +192,28 @@ ScreenshotWindow::MessageReceived(BMessage* message) fOutputPathPanel->SetButtonLabel(B_DEFAULT_BUTTON, "Select"); } fOutputPathPanel->Show(); - } break; - - case B_CANCEL: { + break; + } + + case B_CANCEL: fLastSelectedPath->SetMarked(true); - } break; + break; - case B_REFS_RECEIVED: { + case B_REFS_RECEIVED: + { entry_ref ref; if (message->FindRef("refs", &ref) == B_OK) { BString path(BPath(&ref).Path()); int32 index = _PathIndexInMenu(path); - if (index < 0) { - _AddItemToPathMenu(path.String(), - path, fOutputPathMenu->CountItems() - 2, true); - } else { + if (index < 0) + _AddItemToPathMenu(path.String(), path, + fOutputPathMenu->CountItems() - 2, true); + else fOutputPathMenu->ItemAt(index)->SetMarked(true); - } } - } break; - + break; + } + case kFinishScreenshot: _WriteSettings(); if (_SaveScreenshot() != B_OK) @@ -204,21 +222,43 @@ ScreenshotWindow::MessageReceived(BMessage* message) // fall through case B_QUIT_REQUESTED: be_app_messenger.SendMessage(B_QUIT_REQUESTED); - break; + break; - case kShowOptions: { + case kShowOptions: + { BCardLayout* layout = dynamic_cast (GetLayout()); + if (layout) layout->SetVisibleItem(0L); + SetTitle("Take Screenshot"); fBackToSave->SetEnabled(true); - } break; + break; + } - default: { + default: BWindow::MessageReceived(message); - } break; - }; + break; + } +} + +BPath +ScreenshotWindow::_GetDirectory() +{ + BPath path; + if (!fSaveScreenshotSilent) { + BMessage* message = fLastSelectedPath->Message(); + const char* stringPath; + if (!message || message->FindString("path", &stringPath) != B_OK) { + fprintf(stderr, "failed to find path in message\n"); + } else + path.SetTo(stringPath); + } else { + if (find_directory(B_USER_DIRECTORY, &path) != B_OK) + fprintf(stderr, "failed to find user home folder\n"); + } + return path; } @@ -235,9 +275,8 @@ ScreenshotWindow::_InitWindow() _TakeScreenshot(); _UpdatePreviewPanel(); layout->SetVisibleItem(1L); - } else { + } else layout->SetVisibleItem(0L); - } } @@ -249,9 +288,9 @@ ScreenshotWindow::_SetupFirstLayoutItem(BCardLayout* layout) stringView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); fActiveWindow = new BRadioButton("Capture active window", - new BMessage(kScreenshotType)); + new BMessage(kScreenshotType)); fWholeDesktop = new BRadioButton("Capture entire screen", - new BMessage(kScreenshotType)); + new BMessage(kScreenshotType)); fWholeDesktop->SetValue(B_CONTROL_ON); BString delay; @@ -337,8 +376,8 @@ ScreenshotWindow::_SetupSecondLayoutItem(BCardLayout* layout) _SetupOutputPathMenu(new BMenu("Please select"), settings); BMenuField* menuField2 = new BMenuField("Save in:", fOutputPathMenu); - - fNameControl->SetText(_FindValidFileName("screenshot1").String()); + + fNameControl->SetText(_FindValidFileName("screenshot1")); _SetupTranslatorMenu(new BMenu("Please select"), settings); BMenuField* menuField = new BMenuField("Save as:", fTranslatorMenu); @@ -458,10 +497,9 @@ ScreenshotWindow::_SetupOutputPathMenu(BMenu* outputPathMenu, if (settings.IsEmpty() || lastSelectedPath.Length() == 0) { fOutputPathMenu->ItemAt(1)->SetMarked(true); fLastSelectedPath = fOutputPathMenu->ItemAt(1); - } else { + } else _AddItemToPathMenu(lastSelectedPath.String(), lastSelectedPath, 3, true); - } } fOutputPathMenu->AddItem(new BSeparatorItem()); @@ -489,15 +527,6 @@ ScreenshotWindow::_AddItemToPathMenu(const char* path, BString& label, } -void -ScreenshotWindow::_CenterAndShow() -{ - CenterOnScreen(); - - Show(); -} - - void ScreenshotWindow::_UpdatePreviewPanel() { @@ -528,27 +557,25 @@ ScreenshotWindow::_UpdatePreviewPanel() } -BString +const char* ScreenshotWindow::_FindValidFileName(const char* name) { BString baseName(name); - - if (fExtension.Compare("")) { + + if (fExtension.Compare("")) baseName.RemoveLast(fExtension); - } - if (!fLastSelectedPath) + if (!fSaveScreenshotSilent && !fLastSelectedPath) return baseName; - - const char* path; - BMessage* message = fLastSelectedPath->Message(); - if (!message || message->FindString("path", &path) != B_OK) + + BPath orgPath(_GetDirectory()); + if (orgPath == NULL) return baseName; - + BTranslatorRoster* roster = BTranslatorRoster::Default(); const translation_format* formats = NULL; - int32 numFormats; + int32 numFormats; if (roster->GetOutputFormats(fTranslator, &formats, &numFormats) == B_OK) { for (int32 i = 0; i < numFormats; ++i) { if (formats[i].type == uint32(fImageFileType)) { @@ -559,16 +586,15 @@ ScreenshotWindow::_FindValidFileName(const char* name) if (msgExtensions.FindString("extensions", 0, &extension) == B_OK) { fExtension.SetTo(extension); fExtension.Prepend("."); - } - else + } else fExtension.SetTo(""); } break; } } } - - BPath outputPath(path); + + BPath outputPath = orgPath; BString fileName; fileName << baseName << fExtension; outputPath.Append(fileName); @@ -585,12 +611,12 @@ ScreenshotWindow::_FindValidFileName(const char* name) do { sprintf(filename, "%s%ld%s", baseName.String(), index++, fExtension.String()); - outputPath.SetTo(path); + outputPath.SetTo(orgPath.Path()); outputPath.Append(filename); entry.SetTo(outputPath.Path()); } while (entry.Exists()); - return BString(filename); + return BString(filename).String(); } @@ -679,9 +705,8 @@ ScreenshotWindow::_TakeScreenshot() BScreen(this).ReadBitmap(fScreenshot, fIncludeMouse, &frame); if (fIncludeBorder) _MakeTabSpaceTransparent(&frame); - } else { + } else BScreen(this).GetBitmap(&fScreenshot, fIncludeMouse); - } } @@ -738,38 +763,40 @@ ScreenshotWindow::_GetActiveWindowFrame(BRect* frame) status_t ScreenshotWindow::_SaveScreenshot() { - if (!fScreenshot || !fLastSelectedPath) - return B_ERROR; - - const char* _path; - BMessage* message = fLastSelectedPath->Message(); - if (!message || message->FindString("path", &_path) != B_OK) + if (!fScreenshot || (!fSaveScreenshotSilent && !fLastSelectedPath)) + return B_ERROR; + + BPath path(_GetDirectory()); + + if (path == NULL) return B_ERROR; + if (fSaveScreenshotSilent) + path.Append(_FindValidFileName("screenshot1")); + else + path.Append(fNameControl->Text()); + BEntry entry; - BPath path; - - path = _path; - path.Append(fNameControl->Text()); entry.SetTo(path.Path()); + + if (!fSaveScreenshotSilent) { + if (entry.Exists()) { + BAlert *overwriteAlert = new BAlert("overwrite", "This file " + "already exists.\n Are you sure would you like to overwrite " + "it?", "Cancel", "Overwrite", NULL, B_WIDTH_AS_USUAL, + B_EVEN_SPACING, B_WARNING_ALERT); - if (entry.Exists()) { - BAlert *overwriteAlert = new BAlert("overwrite", "This file already exists.\n" - "Are you sure would you like to overwrite it?", - "Cancel", "Overwrite", NULL, - B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT); - - overwriteAlert->SetShortcut(0, B_ESCAPE); - int32 buttonIndex = overwriteAlert->Go(); - if (buttonIndex == 0) { - return B_CANCELED; - } + overwriteAlert->SetShortcut(0, B_ESCAPE); + + if (overwriteAlert->Go() == 0) + return B_CANCELED; + } } - + BFile file(&entry, B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY); - if (file.InitCheck() != B_OK) { + if (file.InitCheck() != B_OK) return B_ERROR; - } + BBitmapStream bitmapStream(fScreenshot); BTranslatorRoster* roster = BTranslatorRoster::Default(); roster->Translate(&bitmapStream, NULL, NULL, &file, fImageFileType, @@ -795,36 +822,6 @@ ScreenshotWindow::_SaveScreenshot() } -void -ScreenshotWindow::_SaveScreenshotSilent() const -{ - if (!fScreenshot) - return; - - BPath homePath; - if (find_directory(B_USER_DIRECTORY, &homePath) != B_OK) { - fprintf(stderr, "failed to find user home folder\n"); - return; - } - - BPath path; - BEntry entry; - int32 index = 1; - do { - char filename[32]; - sprintf(filename, "screenshot%ld.png", index++); - path = homePath; - path.Append(filename); - entry.SetTo(path.Path()); - } while (entry.Exists()); - - // Dump to PNG - SaveToPNG(path.Path(), fScreenshot->Bounds(), fScreenshot->ColorSpace(), - fScreenshot->Bits(), fScreenshot->BitsLength(), - fScreenshot->BytesPerRow()); -} - - void ScreenshotWindow::_MakeTabSpaceTransparent(BRect* frame) { @@ -901,7 +898,7 @@ ScreenshotWindow::_MakeTabSpaceTransparent(BRect* frame) BView view(fScreenshot->Bounds(), "bitmap", B_FOLLOW_ALL_SIDES, 0); fScreenshot->AddChild(&view); - if(view.Looper() && view.Looper()->Lock()) { + if (view.Looper() && view.Looper()->Lock()) { view.SetDrawingMode(B_OP_COPY); view.SetHighColor(B_TRANSPARENT_32_BIT); @@ -913,4 +910,3 @@ ScreenshotWindow::_MakeTabSpaceTransparent(BRect* frame) } fScreenshot->RemoveChild(&view); } - diff --git a/src/apps/screenshot/ScreenshotWindow.h b/src/apps/screenshot/ScreenshotWindow.h index f2eb795349..4fa8b13206 100644 --- a/src/apps/screenshot/ScreenshotWindow.h +++ b/src/apps/screenshot/ScreenshotWindow.h @@ -1,14 +1,21 @@ /* * Copyright Karsten Heimrich, host.haiku@gmx.de. All rights reserved. * Distributed under the terms of the MIT License. + * + * Authors: + * Karsten Heimrich + * Fredrik Modéen */ +#ifndef SCREENSHOT_WINDOW_H +#define SCREENSHOT_WINDOW_H + + #include #include +#include -#include "PreviewView.h" class BBitmap; -class BBox; class BButton; class BCardLayout; class BCheckBox; @@ -17,6 +24,8 @@ class BMenu; class BRadioButton; class BTextControl; class BTextView; +class BPath; +class PreviewView; class ScreenshotWindow : public BWindow { @@ -26,13 +35,16 @@ public: bool includeMouse = false, bool grabActiveWindow = false, bool showConfigWindow = false, - bool saveScreenshotSilent = false); + bool saveScreenshotSilent = false, + int32 imageFileType = B_PNG_FORMAT, + int32 translator = 8); virtual ~ScreenshotWindow(); virtual void MessageReceived(BMessage* message); private: void _InitWindow(); + BPath _GetDirectory(); void _SetupFirstLayoutItem(BCardLayout* layout); void _SetupSecondLayoutItem(BCardLayout* layout); void _DisallowChar(BTextView* textView); @@ -42,10 +54,9 @@ private: const BMessage& settings); void _AddItemToPathMenu(const char* path, BString& label, int32 index, bool markItem); - void _CenterAndShow(); void _UpdatePreviewPanel(); - BString _FindValidFileName(const char* name); + const char* _FindValidFileName(const char* name); int32 _PathIndexInMenu(const BString& path) const; BMessage _ReadSettings() const; @@ -56,9 +67,7 @@ private: void _MakeTabSpaceTransparent(BRect* frame); status_t _SaveScreenshot(); - void _SaveScreenshotSilent() const; -private: PreviewView* fPreview; BRadioButton* fActiveWindow; BRadioButton* fWholeDesktop; @@ -81,8 +90,11 @@ private: bool fIncludeMouse; bool fGrabActiveWindow; bool fShowConfigWindow; + bool fSaveScreenshotSilent; BString fExtension; int32 fTranslator; int32 fImageFileType; }; + +#endif /* SCREENSHOT_WINDOW_H */