lib: added implicit ctor converter from DatabaseDatabase to DBListType
[barry/progweb.git] / desktop / src / ContactPhotoWidget.cc
blobf43432b7207fcbd1b0f13136f1c543f2c86ccac5
1 ///
2 /// \file ContactPhotoWidget.cc
3 /// Bitmap button that shows a Contact::Image photo
4 ///
6 /*
7 Copyright (C) 2011-2012, Net Direct Inc. (http://www.netdirect.ca/)
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU General Public License in the COPYING file at the
19 root directory of this project for more details.
22 #include "ContactPhotoWidget.h"
23 #include "windowids.h"
24 #include <barry/barry.h>
25 #include <wx/mstream.h>
26 #include <iostream>
27 #include <fstream>
29 using namespace std;
31 #define MAX_IMAGE_HEIGHT 60
32 #define DEFAULT_IMAGE_WIDTH 50
34 ContactPhotoWidget::ContactPhotoWidget(wxWindow *parent,
35 wxWindowID id,
36 Barry::Contact &rec)
37 : m_rec(rec)
38 , m_file_filter(_T("Image files (*.bmp;*.jpg;*.png;*.xmp;*.tif)|*.bmp;*.jpg;*.png;*.xmp;*.tif;*.tiff|All files (*.*)|*.*"))
40 // limit size of image to 60 px height
41 int max_height = MAX_IMAGE_HEIGHT, width = 0;
43 if( m_rec.Image.size() ) {
44 width = LoadRecImage(max_height);
47 // anything loaded? if not, load "empty" bitmap
48 if( !m_bitmap.get() ) {
49 width = DEFAULT_IMAGE_WIDTH;
50 max_height = MAX_IMAGE_HEIGHT;
51 m_bitmap.reset( new wxBitmap(width, max_height) );
52 DrawNoPhoto(*m_bitmap, width, max_height);
55 // have bitmap, create our bitmap button
56 Create(parent, id, *m_bitmap, wxDefaultPosition,
57 wxSize(width, max_height));
60 int ContactPhotoWidget::LoadRecImage(int max_height)
62 // load m_rec.Image into a wxBitmap
63 wxMemoryInputStream stream(m_rec.Image.data(), m_rec.Image.size());
64 wxImage jpeg(stream, wxBITMAP_TYPE_JPEG);
66 float ratio = (float)max_height / jpeg.GetHeight();
67 int width = jpeg.GetWidth() * ratio;
69 jpeg.Rescale(width, max_height, wxIMAGE_QUALITY_HIGH);
70 m_bitmap.reset( new wxBitmap(jpeg) );
71 return width;
74 void ContactPhotoWidget::PromptAndSave(wxWindow *parent)
76 if( !m_rec.Image.size() ) {
77 wxMessageBox(_T("There is no photo available to save."),
78 _T("No Photo"),
79 wxICON_INFORMATION | wxOK);
80 return;
83 wxFileDialog dlg(parent, _T("Save Photo as JPEG..."), _T(""), _T(""),
84 _T("JPEG files (*.jpg)|*.jpg"),
85 wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxFD_PREVIEW);
86 if( dlg.ShowModal() == wxID_OK ) {
87 ofstream ofs(dlg.GetPath().utf8_str(), ios::binary);
88 ofs.write(m_rec.Image.data(), m_rec.Image.size());
92 /// Returns true if a new image has been loaded (may want to resize)
93 bool ContactPhotoWidget::PromptAndLoad(wxWindow *parent)
95 wxFileDialog dlg(parent, _T("Load Photo..."), _T(""), _T(""),
96 m_file_filter,
97 wxFD_OPEN | wxFD_PREVIEW);
98 if( dlg.ShowModal() != wxID_OK )
99 return false;
101 // Load image in whatever format it's in
102 wxImage image;
103 if( !image.LoadFile(dlg.GetPath()) ) {
104 wxMessageBox(_T("Unable to load selected photo."),
105 _T("Photo Load Error"),
106 wxICON_ERROR | wxOK);
107 return false;
110 // Save image to memory as a JPEG
111 wxMemoryOutputStream stream;
112 if( !image.SaveFile(stream, wxBITMAP_TYPE_JPEG) ) {
113 wxMessageBox(_T("Unable to convert image to JPEG."),
114 _T("Photo Convert"),
115 wxICON_ERROR | wxOK);
116 return false;
119 // Store into Contact record
120 const char
121 *begin = (char*)stream.GetOutputStreamBuffer()->GetBufferStart(),
122 *end = (char*)stream.GetOutputStreamBuffer()->GetBufferEnd();
123 int size = end - begin;
124 m_rec.Image.assign(begin, size);
126 // Update our button
127 LoadRecImage(MAX_IMAGE_HEIGHT);
128 SetBitmapLabel(*m_bitmap);
129 SetSize(m_bitmap->GetWidth(), m_bitmap->GetHeight());
130 return true;
133 void ContactPhotoWidget::DeletePhoto()
135 // zap the record
136 m_rec.Image.clear();
138 // replace with message
139 wxSize client = GetClientSize();
140 int width = client.GetWidth();
141 int height = client.GetHeight();
142 m_bitmap.reset( new wxBitmap(width, height) );
143 DrawNoPhoto(*m_bitmap, width, height);
144 SetBitmapLabel(*m_bitmap);
147 void ContactPhotoWidget::DrawNoPhoto(wxBitmap &bm, int width, int height)
149 wxMemoryDC dc;
150 dc.SelectObject(bm);
152 // resources
153 wxColour textcolour(0xa9, 0xa5, 0xa2);
154 wxColour background(0xed, 0xec, 0xeb);
155 wxPen pen(background);
156 wxBrush brush(background);
157 wxString line1(_T("No")), line2(_T("Photo"));
158 int pointsize =wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)
159 .GetPointSize();
160 wxFont font(pointsize, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL,
161 wxFONTWEIGHT_NORMAL);
163 // trim fontsize so it fits
164 wxSize line1_extent, line2_extent;
165 do {
166 font.SetPointSize(pointsize--);
167 dc.SetFont(font);
168 line1_extent = dc.GetTextExtent(line1);
169 line2_extent = dc.GetTextExtent(line2);
170 } while( line1_extent.GetWidth() > width ||
171 line2_extent.GetWidth() > width);
173 // setup DC
174 dc.SetPen(pen);
175 dc.SetBrush(brush);
176 dc.SetTextForeground(textcolour);
177 dc.SetTextBackground(background);
179 // calculate position
180 int total_height = line1_extent.GetHeight() + line2_extent.GetHeight();
181 int y1_start = (height - total_height) / 2;
182 int y2_start = y1_start + line1_extent.GetHeight();
183 int x1_start = (width - line1_extent.GetWidth()) / 2;
184 int x2_start = (width - line2_extent.GetWidth()) / 2;
186 // draw
187 dc.DrawRectangle(0, 0, width, height);
188 dc.DrawText(line1, x1_start, y1_start);
189 dc.DrawText(line2, x2_start, y2_start);
191 // cleanup
192 dc.SetPen(wxNullPen);
193 dc.SetBrush(wxNullBrush);