diff --git a/include/gtimeline.h b/include/gtimeline.h index 4e62dd7d..91e8e3db 100644 --- a/include/gtimeline.h +++ b/include/gtimeline.h @@ -603,6 +603,9 @@ class gTimeline: public wxFrame, public gWindow void OnPopUpSaveCFG( wxCommandEvent& event ); void OnPopUpSaveImageDialog( wxCommandEvent& event ); void OnPopUpSaveText( wxCommandEvent& event ); + void OnPopUpSaveToClipboardWithLegend( wxCommandEvent& event ); + void OnPopUpSaveToClipboardWithOutLegend( wxCommandEvent& event ); + void OnPopUpSaveToClipboardLegend( wxCommandEvent& event ); void OnMenuGradientFunction( TGradientFunction function ); @@ -629,6 +632,8 @@ class gTimeline: public wxFrame, public gWindow void OnItemColorLeftUp( wxMouseEvent& event ); void saveImage( wxString whichFileName = _( "" ), TImageFormat filterIndex = TImageFormat::PNG ); + void saveImageToClipboard(bool withLegend); + void saveLegendToClipboard(); void saveImageLegend( wxString whichFileName = _( "" ), TImageFormat filterIndex = TImageFormat::PNG, bool appendLegendSuffix = true ); @@ -641,7 +646,16 @@ class gTimeline: public wxFrame, public gWindow static wxProgressDialog *dialogProgress; static int numberOfProgressDialogUsers; + + private: + // Gets the Bitmap for saveImage and saveImageToClipboard + // @param withLegend is doing a best effort + // as its only makes sense to embed the legend with + // continous data representation + wxBitmap getBitmapForImage(bool withLegend); + wxBitmap getBitmapForLegend(TImageFormat filterIndex); + public: // void OnRightClick(wxMouseEvent& event); ////@begin gTimeline member variables @@ -856,14 +870,13 @@ class gTimeline: public wxFrame, public gWindow wxColour whichForeground, int whichBackgroundMode, // wxSOLID or wxTRANSPARENT; wxTRANSPARENT overrides fore and back wxFont whichTextFont, - wxString& whichImagePath, const wxString& whichImageInfix, wxBitmapType& whichImageType ); virtual ~ScaleImageVertical(); void process(); - void save(); + void save(const wxString &imagePath); wxImage *getImage() { return scaleImage; } wxBitmap *getBitmap() { return scaleBitmap; } @@ -875,7 +888,7 @@ class gTimeline: public wxFrame, public gWindow virtual void createDC(); virtual void draw(); virtual void bitmapToImage(); - virtual wxString buildScaleImagePath(); + virtual wxString buildScaleImagePath(const wxString &imagePath); virtual void drawLabeledRectangle( rgb semanticColour, wxString semanticValueLabel, bool drawIt = true ); @@ -887,7 +900,6 @@ class gTimeline: public wxFrame, public gWindow wxColour foreground; int backgroundMode; wxFont textFont; - wxString& imagePath; wxString imageInfix; wxBitmapType& imageType; TImageFormat filterIndex; @@ -929,7 +941,6 @@ class gTimeline: public wxFrame, public gWindow wxColour whichForeground, int whichBackgroundMode, wxFont whichTextFont, - wxString& whichImagePath, const wxString& whichImageInfix, wxBitmapType& whichImageType ); @@ -950,7 +961,6 @@ class gTimeline: public wxFrame, public gWindow wxColour whichForeground, int whichBackgroundMode, wxFont whichTextFont, - wxString& whichImagePath, const wxString& whichImageInfix, wxBitmapType& whichImageType ); @@ -976,7 +986,6 @@ class gTimeline: public wxFrame, public gWindow wxColour whichForeground, int whichBackgroundMode, wxFont whichTextFont, - wxString& whichImagePath, const wxString& whichImageInfix, wxBitmapType& whichImageType ); @@ -999,7 +1008,6 @@ class gTimeline: public wxFrame, public gWindow wxColour whichForeground, int whichBackgroundMode, wxFont whichTextFont, - wxString& whichImagePath, const wxString& whichImageInfix, wxBitmapType& whichImageType, int whichWantedWidth = 0 ); diff --git a/include/popupmenu.h b/include/popupmenu.h index 273734e5..ede75807 100644 --- a/include/popupmenu.h +++ b/include/popupmenu.h @@ -144,6 +144,9 @@ #define ID_MENU_PROFET 30108 #define ID_MENU_ALTERNATIVE_GRADIENT_COLOR 30109 #define ID_MENU_ALTERNATIVE_GRADIENT_COLOR_2D 30110 +#define ID_MENU_SAVE_TO_CLIPBOARD_WITH_LEGEND 30111 +#define ID_MENU_SAVE_TO_CLIPBOARD_WO_LEGEND 30112 +#define ID_MENU_SAVE_TO_CLIPBOARD_LEGEND 30113 #define ID_MENU_SYNC_GROUP_BASE 31000 #define ID_MENU_SYNC_REMOVE_GROUP_BASE 32000 @@ -190,6 +193,8 @@ class gPopUpMenu : public wxMenu wxMenu *popUpMenuLabels; wxMenu *popUpMenuObjectAxis; wxMenu *popUpMenuSave; + // only used in timeline for now + wxMenu *popUpMenuCopy; wxMenu *popUpMenuRun; wxMenu *popUpMenuSync; wxMenu *popUpMenuSyncRemove; diff --git a/src/gtimeline.cpp b/src/gtimeline.cpp index bb15bcc7..52544e0f 100644 --- a/src/gtimeline.cpp +++ b/src/gtimeline.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include "config_traits.h" #include "wxparaverapp.h" @@ -3471,6 +3472,24 @@ void gTimeline::OnPopUpSaveText( wxCommandEvent& event ) saveText(); } + +void gTimeline::OnPopUpSaveToClipboardWithLegend( wxCommandEvent& event ) +{ + saveImageToClipboard(true); +} + +void gTimeline::OnPopUpSaveToClipboardWithOutLegend( wxCommandEvent& event ) +{ + saveImageToClipboard(false); +} + + +void gTimeline::OnPopUpSaveToClipboardLegend( wxCommandEvent& event ) +{ + saveLegendToClipboard(); +} + + void gTimeline::Unsplit() { canRedraw = false; @@ -3829,6 +3848,8 @@ wxString gTimeline::buildFormattedFileName() const } + + void gTimeline::saveImageDialog( wxString whichFileName ) { wxString imageName; @@ -3877,11 +3898,10 @@ void gTimeline::saveImageDialog( wxString whichFileName ) void gTimeline::saveImage( wxString whichFileName, TImageFormat filterIndex ) { - wxString imagePath; - /* TImageFormat filterIndex;*/ - + setEnableDestroyButton( false ); - + // construct valid imagePath + wxString imagePath; if( !whichFileName.IsEmpty() ) { imagePath = whichFileName; @@ -3906,7 +3926,37 @@ void gTimeline::saveImage( wxString whichFileName, TImageFormat filterIndex ) wxString::FromUTF8( LabelConstructor::getImageFileSuffix( filterIndex ).c_str() ); imagePath = imageName + tmpSuffix; } - + + // Select imageType + wxBitmapType imageType = wxBITMAP_TYPE_PNG; + switch( filterIndex ) + { + case TImageFormat::BMP: + imageType = wxBITMAP_TYPE_BMP; + break; + case TImageFormat::JPG: + imageType = wxBITMAP_TYPE_JPEG; + break; + case TImageFormat::PNG: + imageType = wxBITMAP_TYPE_PNG; + break; + case TImageFormat::XPM: + imageType = wxBITMAP_TYPE_XPM; + break; + default: + imageType = wxBITMAP_TYPE_PNG; + break; + } + + wxBitmap bitmap = this->getBitmapForImage(true); + wxImage finalImage = bitmap.ConvertToImage(); + finalImage.SaveFile( imagePath, imageType ); + setEnableDestroyButton( true ); +} + +// Return the current timeline as bitmap to be used in saveImage and to +// be copied to the clipboard +wxBitmap gTimeline::getBitmapForImage(bool withLegend){ // Get title wxString longTitle = wxString::FromUTF8( ( myWindow->getName() + " @ " + @@ -3983,32 +4033,14 @@ void gTimeline::saveImage( wxString whichFileName, TImageFormat filterIndex ) // Get image type and save wxBitmapType imageType; - switch( filterIndex ) - { - case TImageFormat::BMP: - imageType = wxBITMAP_TYPE_BMP; - break; - case TImageFormat::JPG: - imageType = wxBITMAP_TYPE_JPEG; - break; - case TImageFormat::PNG: - imageType = wxBITMAP_TYPE_PNG; - break; - case TImageFormat::XPM: - imageType = wxBITMAP_TYPE_XPM; - break; - default: - imageType = wxBITMAP_TYPE_PNG; - break; - } - imageDC.SelectObject( wxNullBitmap ); wxImage baseLayer = imageBitmap.ConvertToImage(); - // Save timeline with gradient scale - if ( myWindow->isGradientColorSet() || + // Return timeline with gradient scale + if ( (myWindow->isGradientColorSet() || myWindow->isNotNullGradientColorSet() || - myWindow->isAlternativeGradientColorSet() ) + myWindow->isAlternativeGradientColorSet()) + && withLegend ) { ScaleImageVertical *tmpImage; @@ -4023,7 +4055,7 @@ void gTimeline::saveImage( wxString whichFileName, TImageFormat filterIndex ) semanticValuesToColor, backgroundColour, foregroundColour, backgroundMode, titleFont, - imagePath, wxString( _( "horiz.labels" ) ), + wxString( _( "horiz.labels" ) ), imageType, wantedWidth ); tmpImage->process(); @@ -4062,25 +4094,124 @@ void gTimeline::saveImage( wxString whichFileName, TImageFormat filterIndex ) &tmpScaleDC, xsrc, ysrc ); - //tmpScaledTimelineDC->SelectObject( wxNullBitmap ); - wxImage tmpScaledTimeline( tmpScaledTimelineBitmap.ConvertToImage() ); - wxString currentFormat = - wxString::FromUTF8( LabelConstructor::getImageFileSuffix( - TImageFormat( filterIndex ) ).c_str() ); - wxString tmpScaledTimelinePath = wxFileName( imagePath ).GetPathWithSep() + - wxFileName( imagePath ).GetName() + - wxString( _(".w_legend.") ) + - currentFormat; - tmpScaledTimeline.SaveFile( tmpScaledTimelinePath, imageType ); + return tmpScaledTimelineBitmap; + } + else{ + // Return the bitmap without gradient scale + return baseLayer; } +} - // Save timeline image without scale - baseLayer.SaveFile( imagePath, imageType ); +wxBitmap gTimeline::getBitmapForLegend(TImageFormat filterIndex){ + // for now this duplicates a bit of code with saveImageLegend(), but i think + // saveImageLegend can be refactored to use getBitmapforLegend + // Get colors + wxColour foregroundColour = GetForegroundColour(); + wxColour backgroundColour = GetBackgroundColour(); + // Get font + wxFont titleFont = semanticFont; + + // Get image type and save + wxBitmapType imageType; + + int backgroundMode = wxTRANSPARENT; // default + switch( filterIndex ) + { + case TImageFormat::BMP: + backgroundMode = wxSOLID; + break; + case TImageFormat::JPG: + backgroundMode = wxSOLID; + break; + } + + if ( myWindow->isGradientColorSet() || + myWindow->isNotNullGradientColorSet() || + myWindow->isAlternativeGradientColorSet() ) + { + auto tmpImage = ScaleImageHorizontalGradientColor( myWindow, semanticValuesToColor, + //backgroundColour, foregroundColour, backgroundMode, + *wxWHITE, *wxBLACK, backgroundMode, + titleFont, + wxString( _( "" ) ), + imageType ); + tmpImage.process(); + return *tmpImage.getBitmap(); + } + else if ( myWindow->isCodeColorSet() ) + { + auto tmpImage = ScaleImageVerticalCodeColor( myWindow, semanticValuesToColor, + //backgroundColour, foregroundColour, backgroundMode, + *wxWHITE, *wxBLACK, backgroundMode, + titleFont, + wxString( _( "" ) ), + imageType ); + tmpImage.process(); + return *tmpImage.getBitmap(); + } + else if ( myWindow->isFusedLinesColorSet() ) + { + std::map< TSemanticValue, rgb > tmpObjects; + + TObjectOrder beginRow = myWindow->getZoomSecondDimension().first; + TObjectOrder endRow = myWindow->getZoomSecondDimension().second; + vector selected; + myWindow->getSelectedRows( myWindow->getLevel(), selected, beginRow, endRow, true ); + + for( vector::iterator it = selected.begin(); it != selected.end(); ++it ) + { + rgb tmprgb = myWindow->getSemanticColor().calcColor( (*it) + 1, 0, myWindow->getTrace()->getLevelObjects( myWindow->getLevel() ) - 1 ); + tmpObjects[ (TSemanticValue)(*it) ] = tmprgb; + } + auto tmpImage = ScaleImageVerticalFusedLines( myWindow, tmpObjects, + //backgroundColour, foregroundColour, backgroundMode, + *wxWHITE, *wxBLACK, backgroundMode, + titleFont, + wxString( _( "" ) ), + imageType ); + tmpImage.process(); + return *tmpImage.getBitmap(); + } + // fallback to empty bitmap + return wxBitmap(); +} + +void gTimeline::saveImageToClipboard(bool withLegend) +{ + setEnableDestroyButton( false ); + wxBitmap bitmap = this->getBitmapForImage(withLegend); + + if (wxTheClipboard->Open()) + { + // This data objects are held by the clipboard, + // so do not delete them in the app. + if(!wxTheClipboard->SetData( new wxBitmapDataObject(bitmap) )){ + std::cout<< "Could not copy to clipboard" <Close(); + } + setEnableDestroyButton( true ); } +void gTimeline::saveLegendToClipboard(){ + + setEnableDestroyButton( false ); + wxBitmap bitmap = this->getBitmapForLegend(TImageFormat::PNG); + + if (wxTheClipboard->Open()) + { + // This data objects are held by the clipboard, + // so do not delete them in the app. + if(!wxTheClipboard->SetData( new wxBitmapDataObject(bitmap) )){ + std::cout<< "Could not copy to clipboard" <Close(); + } + setEnableDestroyButton( true ); +} void gTimeline::saveImageLegend( wxString whichFileName, TImageFormat filterIndex, bool appendLegendSuffix ) { @@ -4170,11 +4301,10 @@ void gTimeline::saveImageLegend( wxString whichFileName, TImageFormat filterInde //backgroundColour, foregroundColour, backgroundMode, *wxWHITE, *wxBLACK, backgroundMode, titleFont, - //imagePath, wxString( _( "horiz.labels.transp" ) ), - imagePath, wxString( _( "" ) ), + wxString( _( "" ) ), imageType ); tmpImage->process(); - tmpImage->save(); + tmpImage->save(imagePath); delete tmpImage; } else if ( myWindow->isCodeColorSet() ) @@ -4183,11 +4313,10 @@ void gTimeline::saveImageLegend( wxString whichFileName, TImageFormat filterInde //backgroundColour, foregroundColour, backgroundMode, *wxWHITE, *wxBLACK, backgroundMode, titleFont, - // imagePath, wxString( _( "vert.labels.transp" ) ), - imagePath, wxString( _( "" ) ), + wxString( _( "" ) ), imageType ); tmpImage->process(); - tmpImage->save(); + tmpImage->save(imagePath); delete tmpImage; } else if ( myWindow->isFusedLinesColorSet() ) @@ -4208,11 +4337,10 @@ void gTimeline::saveImageLegend( wxString whichFileName, TImageFormat filterInde //backgroundColour, foregroundColour, backgroundMode, *wxWHITE, *wxBLACK, backgroundMode, titleFont, - // imagePath, wxString( _( "vert.labels.transp" ) ), - imagePath, wxString( _( "" ) ), + wxString( _( "" ) ), imageType ); tmpImage->process(); - tmpImage->save(); + tmpImage->save(imagePath); delete tmpImage; } @@ -4232,7 +4360,6 @@ gTimeline::ScaleImageVertical::ScaleImageVertical( wxColour whichForeground, int whichBackgroundMode, wxFont whichTextFont, - wxString& whichImagePath, const wxString& whichImageInfix, wxBitmapType& whichImageType ) : myWindow( whichMyWindow ), @@ -4241,7 +4368,6 @@ gTimeline::ScaleImageVertical::ScaleImageVertical( foreground( whichForeground ), backgroundMode( whichBackgroundMode ), textFont( whichTextFont ), - imagePath( whichImagePath ), imageInfix( whichImageInfix ), imageType( whichImageType ) { @@ -4254,7 +4380,7 @@ gTimeline::ScaleImageVertical::~ScaleImageVertical() } -wxString gTimeline::ScaleImageVertical::buildScaleImagePath() +wxString gTimeline::ScaleImageVertical::buildScaleImagePath(const wxString &imagePath) { wxString scaleImagePath; @@ -4300,9 +4426,9 @@ void gTimeline::ScaleImageVertical::process() } -void gTimeline::ScaleImageVertical::save() +void gTimeline::ScaleImageVertical::save(const wxString &imagePath) { - wxString scaleImagePath = buildScaleImagePath(); + wxString scaleImagePath = buildScaleImagePath(imagePath); scaleImage->SaveFile( scaleImagePath, imageType ); // Test code for transparency @@ -4512,7 +4638,6 @@ gTimeline::ScaleImageVerticalCodeColor::ScaleImageVerticalCodeColor( wxColour whichForeground, int whichBackgroundMode, wxFont whichTextFont, - wxString& whichImagePath, const wxString& whichImageInfix, wxBitmapType& whichImageType ) : ScaleImageVertical( whichMyWindow, @@ -4521,7 +4646,6 @@ gTimeline::ScaleImageVerticalCodeColor::ScaleImageVerticalCodeColor( whichForeground, whichBackgroundMode, whichTextFont, - whichImagePath, whichImageInfix, whichImageType ) { @@ -4548,7 +4672,6 @@ gTimeline::ScaleImageVerticalGradientColor::ScaleImageVerticalGradientColor( wxColour whichForeground, int whichBackgroundMode, wxFont whichTextFont, - wxString& whichImagePath, const wxString& whichImageInfix, wxBitmapType& whichImageType ) : ScaleImageVertical( whichMyWindow, @@ -4557,7 +4680,6 @@ gTimeline::ScaleImageVerticalGradientColor::ScaleImageVerticalGradientColor( whichForeground, whichBackgroundMode, whichTextFont, - whichImagePath, whichImageInfix, whichImageType ) { @@ -4633,7 +4755,6 @@ gTimeline::ScaleImageVerticalFusedLines::ScaleImageVerticalFusedLines( wxColour whichForeground, int whichBackgroundMode, wxFont whichTextFont, - wxString& whichImagePath, const wxString& whichImageInfix, wxBitmapType& whichImageType ) : ScaleImageVertical( whichMyWindow, @@ -4642,7 +4763,6 @@ gTimeline::ScaleImageVerticalFusedLines::ScaleImageVerticalFusedLines( whichForeground, whichBackgroundMode, whichTextFont, - whichImagePath, whichImageInfix, whichImageType ) { @@ -4698,7 +4818,6 @@ gTimeline::ScaleImageHorizontalGradientColor::ScaleImageHorizontalGradientColor( wxColour whichForeground, int whichBackgroundMode, wxFont whichTextFont, - wxString& whichImagePath, const wxString& whichImageInfix, wxBitmapType& whichImageType, int whichWantedWidth @@ -4708,7 +4827,6 @@ gTimeline::ScaleImageHorizontalGradientColor::ScaleImageHorizontalGradientColor( whichForeground, whichBackgroundMode, whichTextFont, - whichImagePath, whichImageInfix, whichImageType ) { diff --git a/src/popupmenu.cpp b/src/popupmenu.cpp index 34d709ba..c572674e 100644 --- a/src/popupmenu.cpp +++ b/src/popupmenu.cpp @@ -277,6 +277,7 @@ gPopUpMenu::gPopUpMenu( gTimeline *whichTimeline ) popUpMenuLabels = new wxMenu; popUpMenuObjectAxis = new wxMenu; popUpMenuSave = new wxMenu; + popUpMenuCopy = new wxMenu; popUpMenuRun = new wxMenu; popUpMenuSync = new wxMenu; popUpMenuSyncRemove = new wxMenu; @@ -661,6 +662,13 @@ gPopUpMenu::gPopUpMenu( gTimeline *whichTimeline ) AppendSeparator(); + AppendSubMenu( popUpMenuCopy, _( "Copy to Clipboard" ) ); + buildItem( popUpMenuCopy, _( "Timeline with Legend" ), wxITEM_NORMAL, &gTimeline::OnPopUpSaveToClipboardWithLegend, ID_MENU_SAVE_TO_CLIPBOARD_WITH_LEGEND ); + buildItem( popUpMenuCopy, _( "Timeline w.o. Legend" ), wxITEM_NORMAL, &gTimeline::OnPopUpSaveToClipboardWithOutLegend, ID_MENU_SAVE_TO_CLIPBOARD_WO_LEGEND ); + buildItem( popUpMenuCopy, _( "Legend" ), wxITEM_NORMAL, &gTimeline::OnPopUpSaveToClipboardLegend, ID_MENU_SAVE_TO_CLIPBOARD_LEGEND ); + + AppendSeparator(); + buildItem( this, _( "Timing\tCTRL+T" ), wxITEM_CHECK, @@ -697,6 +705,7 @@ gPopUpMenu::gPopUpMenu( gHistogram *whichHistogram ) popUpMenuSaveAsText = new wxMenu; popUpMenuColor2D = new wxMenu; popUpMenuSave = new wxMenu; + popUpMenuCopy = new wxMenu; popUpMenuSync = new wxMenu; popUpMenuSyncRemove = new wxMenu;