3 /// Utility functions specific to Barry Desktop
7 Copyright (C) 2009-2013, 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.
23 #include "barrydesktop.h"
24 #include "windowids.h"
25 #include <wx/datectrl.h>
26 #include <wx/tokenzr.h>
32 const wxChar
*ButtonNames
[] = {
37 _T("browsedatabases"),
44 const wxArrayString
& GetButtonLabels()
46 static wxArrayString m_labels
;
48 if( m_labels
.GetCount() == 0 ) {
49 // TRANSLATORS: this is a main screen button label. See
50 // util.cc line 200 for more information on its flexibility.
51 m_labels
.Add( _W("Backup &\nRestore") );
52 // TRANSLATORS: this is a main screen button label
53 m_labels
.Add( _W("Sync") );
54 // TRANSLATORS: this is a main screen button label
55 m_labels
.Add( _W("Modem\nTethering") );
56 // TRANSLATORS: this is a main screen button label
57 m_labels
.Add( _W("Migrate\nDevice") );
58 // TRANSLATORS: this is a main screen button label
59 m_labels
.Add( _W("Browse\nDatabases") );
60 // TRANSLATORS: this is a main screen button label
61 m_labels
.Add( _W("Application\nLoader") );
62 // TRANSLATORS: this is a main screen button label
63 m_labels
.Add( _W("Media") );
64 // TRANSLATORS: this is a main screen button label
65 m_labels
.Add( _W("Misc") );
71 bool ButtonEnabled
[] = {
72 true, // backuprestore
75 true, // migratedevice
76 true, // browsedatabases
83 const wxChar
*StateNames
[] = {
90 //////////////////////////////////////////////////////////////////////////////
93 std::string
GetBaseFilename(const std::string
&filename
)
95 std::string file
= BARRYDESKTOP_BASEDATADIR
;
97 if( wxFileExists(wxString(file
.c_str(), wxConvUTF8
)) )
100 // fall back to the devel tree
104 /// Returns full path and filename for given filename.
105 /// 'filename' should have no directory component, as the
106 /// directory will be prepended and returned.
107 wxString
GetImageFilename(const wxString
&filename
)
109 // try the official install directory first
110 wxString file
= _T(BARRYDESKTOP_IMAGEDIR
);
112 if( wxFileExists(file
) )
115 // oops, assume we're running from the build directory,
116 // and use the images dir
117 file
= wxPathOnly(wxGetApp().argv
[0]);
118 file
+= _T("/../images/");
120 if( wxFileExists(file
) )
123 // hmmm.... maybe we're running from inside the libtool
124 // build subdirectories
125 file
= wxPathOnly(wxGetApp().argv
[0]);
126 file
+= _T("/../../images/");
131 wxString
GetButtonFilename(int id
, int state
)
133 return GetImageFilename(
134 wxString(ButtonNames
[id
- MainMenu_FirstButton
]) +
139 wxString
GetButtonLabel(int id
)
141 return GetButtonLabels()[id
- MainMenu_FirstButton
];
144 bool IsButtonEnabled(int id
)
146 return ButtonEnabled
[id
- MainMenu_FirstButton
];
149 void MakeDateRecent(bool checked
, wxDatePickerCtrl
*picker
)
151 wxDateTime when
= picker
->GetValue();
152 if( checked
&& (!when
.IsValid() ||
153 when
< wxDateTime(1, wxDateTime::Jan
, 1975, 0, 0, 0)) )
155 when
= wxDateTime::Now();
156 picker
->SetValue(when
);
160 bool IsParsable(const std::string
&dbname
)
163 #define HANDLE_PARSER(dbn) \
164 if( dbname == Barry::dbn::GetDBName() ) return true;
166 ALL_KNOWN_PARSER_TYPES
171 bool IsBuildable(const std::string
&dbname
)
173 #undef HANDLE_BUILDER
174 #define HANDLE_BUILDER(dbn) \
175 if( dbname == Barry::dbn::GetDBName() ) return true;
177 ALL_KNOWN_BUILDER_TYPES
189 LabelLine(const wxString
&line
, const wxDC
&dc
)
194 dc
.GetTextExtent(line
, &m_width
, &m_height
);
202 /// Draws the given label text in the specified area of the bitmap,
203 /// modifying the DC in the process (the bitmap is only used for
204 /// sizing). This is intended for use in creating the main Desktop
205 /// buttons, but can be used on any image.
207 /// The left/top/right/bottom coordinates are relative to the 0,0 of
208 /// the bitmap itself, and limit the area where the label text will be
209 /// drawn. If -1 is used for any of the values, the bitmap edge will
210 /// be used. If other negative numbers are used, (edge - value) will
213 /// The label text can contain \n characters to split into multiple
214 /// lines. Each line will be centered (left/right) in the coordinate
215 /// area, and all lines will be centered (top/bottom) in the coordinate
216 /// area. A trailing \n character is not required, and not recommended.
218 /// If the coordinate area is too small for the given text and font,
219 /// the font will be reduced iteratively for a few points and tried again.
220 /// If still too big, a DrawButtonLabelError exception will be thrown.
221 /// Note that the font passed in will be modified in this case, in case
222 /// the new point size needs to be used elsewhere.
224 /// If the label contains an empty string, a DrawButtonLabelError exception will
225 /// be thrown. This is to prevent any unlabeled buttons in the system.
227 /// If Font is invalid, DrawButtonLabelError will be thrown.
229 void DrawButtonLabelDC(wxDC
&dc
, const wxBitmap
&bmp
, const wxString
&label
,
230 wxFont
&font
, const wxColour
&textfg
,
231 int left
, int top
, int right
, int bottom
)
233 // calculate the coordinates, and various sanity checks
234 if( left
== -1 ) left
= 0;
235 if( top
== -1 ) top
= 0;
236 if( right
== -1 ) right
= bmp
.GetWidth();
237 if( bottom
== -1 ) bottom
= bmp
.GetHeight();
239 if( right
< -1 ) right
= bmp
.GetWidth() + right
;
240 if( bottom
< -1 ) bottom
= bmp
.GetHeight() + bottom
;
242 int width
= right
- left
;
245 width
= right
- left
;
248 int height
= bottom
- top
;
251 height
= bottom
- top
;
255 throw DrawButtonLabelError(_C("Unable to create button: font is invalid"));
257 // create DC to work with, writing into the bitmap given to us
259 dc
.SetTextForeground(textfg
);
260 dc
.SetMapMode(wxMM_TEXT
);
262 // build vector of lines, and calculate totals
263 int total_text_height
= 0;
265 std::vector
<LabelLine
> lines
;
267 // ... and keep trying if too big
268 for( int tries
= 0; ; tries
++ ) {
270 total_text_height
= 0;
274 wxStringTokenizer
tokens(label
, _T("\n"));
275 while( tokens
.HasMoreTokens() ) {
276 wxString token
= tokens
.GetNextToken();
280 if( !tokens
.HasMoreTokens() && token
.size() == 0 ) {
281 // we're done here... last line is empty
285 LabelLine
line(token
, dc
);
286 lines
.push_back( line
);
287 total_text_height
+= line
.m_height
;
288 widest_line
= max(widest_line
, line
.m_width
);
291 // do we have enough room?
292 if( total_text_height
<= height
&& widest_line
<= width
) {
297 // only reduce font so much...
299 throw DrawButtonLabelError(_C("Unable to create button: text is too big to fit: ") + string(label
.utf8_str()));
301 // too big, reduce font and try again
302 font
.SetPointSize( font
.GetPointSize() - 1 );
307 if( lines
.size() == 0 )
308 throw DrawButtonLabelError(_C("Unable to create button: label is empty"));
310 // calculate starting height
311 int y
= (height
- total_text_height
) / 2 + top
;
313 // draw each line, centering each one horizontally, and
314 // incrementing y by the line's height on each pass
315 std::vector
<LabelLine
>::iterator b
= lines
.begin(), e
= lines
.end();
316 for( ; b
!= e
; ++b
) {
317 int x
= (width
- b
->m_width
) / 2 + left
;
318 dc
.DrawText(b
->m_line
, x
, y
);