Skip to content

Commit cd940ec

Browse files
committed
Initial work to support the Google API.
1 parent 5702a07 commit cd940ec

File tree

8 files changed

+1172
-0
lines changed

8 files changed

+1172
-0
lines changed

demo/source/MainModule.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "core/SharedObjects.cpp"
44
#include "demos/AnimationDemo.cpp"
55
#include "demos/EffectChainDemo.cpp"
6+
#include "demos/GoogleAPIDemo.cpp"
67
#include "demos/ParticleSystemDemo.cpp"
78
#include "main/DemoLookAndFeel.cpp"
89
#include "main/MainComponent.cpp"

demo/source/MainModule.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "demos/AnimationDemo.h"
2424
#include "demos/CodeEditorDemo.h"
2525
#include "demos/CRCDemo.h"
26+
#include "demos/GoogleAPIDemo.h"
2627
#include "demos/iCUESDKDemo.h"
2728
#include "demos/EasingsDemo.h"
2829
#include "demos/EffectChainDemo.h"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// This file is intentionally empty as the implementation is in the header file
2+

demo/source/demos/GoogleAPIDemo.h

Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
//==============================================================================
2+
/** Example class demonstrating GoogleAPIManager usage */
3+
class GoogleAPIDemo final : public DemoBase
4+
{
5+
public:
6+
/** */
7+
GoogleAPIDemo (SharedObjects& sharedObjs) :
8+
DemoBase (sharedObjs, NEEDS_TRANS ("Google API Manager"))
9+
{
10+
setupUI();
11+
setupGoogleAPI();
12+
}
13+
14+
//==============================================================================
15+
void resized() override
16+
{
17+
auto area = getLocalBounds().reduced (dims::marginPx);
18+
19+
statusLabel.setBounds (area.removeFromTop (30));
20+
area.removeFromTop (10);
21+
22+
authCodeEditor.setBounds (area.removeFromTop (30));
23+
area.removeFromTop (5);
24+
authButton.setBounds (area.removeFromTop (30));
25+
area.removeFromTop (10);
26+
27+
const int buttonHeight = 30;
28+
const int buttonSpacing = 5;
29+
30+
sheetsButton.setBounds (area.removeFromTop (buttonHeight));
31+
area.removeFromTop (buttonSpacing);
32+
docsButton.setBounds (area.removeFromTop (buttonHeight));
33+
area.removeFromTop (buttonSpacing);
34+
gmailButton.setBounds (area.removeFromTop (buttonHeight));
35+
area.removeFromTop (buttonSpacing);
36+
calendarButton.setBounds (area.removeFromTop (buttonHeight));
37+
}
38+
39+
private:
40+
//==============================================================================
41+
GoogleAPIManager apiManager;
42+
43+
// UI Components
44+
Label statusLabel;
45+
TextEditor authCodeEditor;
46+
TextButton authButton { "Authenticate with Code" };
47+
TextButton sheetsButton { "Test Sheets API" };
48+
TextButton docsButton { "Test Docs API" };
49+
TextButton gmailButton { "Test Gmail API" };
50+
TextButton calendarButton { "Test Calendar API" };
51+
52+
//==============================================================================
53+
void setupGoogleAPI()
54+
{
55+
// Set your OAuth2 client credentials (get these from Google Cloud Console)
56+
apiManager.setClientCredentials (
57+
"your_client_id_here.apps.googleusercontent.com",
58+
"your_client_secret_here"
59+
);
60+
61+
// Add the scopes you need
62+
apiManager.addScope (GoogleAPIManager::Scopes::SHEETS_READWRITE);
63+
apiManager.addScope (GoogleAPIManager::Scopes::DOCS_READWRITE);
64+
apiManager.addScope (GoogleAPIManager::Scopes::GMAIL_READWRITE);
65+
apiManager.addScope (GoogleAPIManager::Scopes::CALENDAR_READWRITE);
66+
67+
// Try to authenticate (will load saved credentials if available)
68+
apiManager.authenticate ([this] (bool success, const String& error) {
69+
if (success)
70+
{
71+
Logger::writeToLog ("Authentication successful!");
72+
statusLabel.setText ("Authenticated successfully", dontSendNotification);
73+
enableButtons (true);
74+
}
75+
else
76+
{
77+
Logger::writeToLog ("Authentication failed: " + error);
78+
statusLabel.setText ("Authentication required", dontSendNotification);
79+
80+
// Show authorisation URL for manual authentication
81+
const String authUrl = apiManager.getAuthorizationUrl();
82+
Logger::writeToLog ("Please visit this URL to authorise: " + authUrl);
83+
84+
// In a real app, you might open this URL in a browser
85+
// URL::launchInDefaultBrowser (authUrl);
86+
}
87+
});
88+
}
89+
90+
void authenticateWithCode (const String& authCode)
91+
{
92+
apiManager.authenticateWithCode (authCode, [this] (bool success, const String& error) {
93+
if (success)
94+
{
95+
Logger::writeToLog ("Authentication with code successful!");
96+
statusLabel.setText ("Authenticated successfully", dontSendNotification);
97+
enableButtons (true);
98+
}
99+
else
100+
{
101+
Logger::writeToLog ("Authentication with code failed: " + error);
102+
statusLabel.setText ("Authentication failed: " + error, dontSendNotification);
103+
}
104+
});
105+
}
106+
107+
void demonstrateSheets()
108+
{
109+
Logger::writeToLog ("=== Google Sheets API Demo ===");
110+
111+
// Create a new spreadsheet
112+
apiManager.createSpreadsheet ("Test Spreadsheet from JUCE", [this] (const var& data, const String& error) {
113+
if (! error.isEmpty())
114+
{
115+
Logger::writeToLog ("Error creating spreadsheet: " + error);
116+
return;
117+
}
118+
119+
const String spreadsheetId = data["spreadsheetId"].toString();
120+
Logger::writeToLog ("Created spreadsheet with ID: " + spreadsheetId);
121+
122+
// Add some data to the spreadsheet
123+
var values;
124+
var row1, row2, row3;
125+
row1.append ("Name");
126+
row1.append ("Age");
127+
row1.append ("City");
128+
row2.append ("John");
129+
row2.append (25);
130+
row2.append ("New York");
131+
row3.append ("Jane");
132+
row3.append (30);
133+
row3.append ("London");
134+
135+
values.append (row1);
136+
values.append (row2);
137+
values.append (row3);
138+
139+
apiManager.updateSheetsData (spreadsheetId, "Sheet1!A1:C3", values, [spreadsheetId] (bool success, const String& error) {
140+
if (success)
141+
{
142+
Logger::writeToLog ("Successfully added data to spreadsheet");
143+
144+
// Now read the data back
145+
// Note: 'this' capture might be invalid here in real usage
146+
// You should use weak references or ensure lifetime
147+
}
148+
else
149+
{
150+
Logger::writeToLog ("Error adding data: " + error);
151+
}
152+
});
153+
});
154+
}
155+
156+
void demonstrateDocs()
157+
{
158+
Logger::writeToLog ("=== Google Docs API Demo ===");
159+
160+
// Create a new document
161+
apiManager.createDocument ("Test Document from JUCE", [this] (const var& data, const String& error) {
162+
if (! error.isEmpty())
163+
{
164+
Logger::writeToLog ("Error creating document: " + error);
165+
return;
166+
}
167+
168+
const String documentId = data["documentId"].toString();
169+
Logger::writeToLog ("Created document with ID: " + documentId);
170+
171+
// Insert some text
172+
apiManager.insertText (documentId, 1, "Hello from JUCE!\n\nThis document was created using the GoogleAPIManager class.",
173+
[documentId] (bool success, const String& error) {
174+
if (success)
175+
Logger::writeToLog ("Successfully inserted text into document");
176+
else
177+
Logger::writeToLog ("Error inserting text: " + error);
178+
});
179+
});
180+
}
181+
182+
void demonstrateGmail()
183+
{
184+
Logger::writeToLog ("=== Gmail API Demo ===");
185+
186+
// Get user profile
187+
apiManager.getProfile ([this] (const var& data, const String& error) {
188+
if (! error.isEmpty())
189+
{
190+
Logger::writeToLog ("Error getting profile: " + error);
191+
return;
192+
}
193+
194+
Logger::writeToLog ("Gmail profile: " + JSON::toString (data));
195+
196+
// Get recent messages
197+
apiManager.getMessages ("", 5, [] (const var& data, const String& error) {
198+
if (! error.isEmpty())
199+
{
200+
Logger::writeToLog ("Error getting messages: " + error);
201+
return;
202+
}
203+
204+
Logger::writeToLog ("Recent messages: " + JSON::toString (data));
205+
});
206+
});
207+
208+
// Send a test email (commented out to avoid spam)
209+
/*
210+
apiManager.sendEmail (
211+
"recipient@example.com",
212+
"Test Email from JUCE",
213+
"Hello!\n\nThis email was sent using the GoogleAPIManager class in JUCE.\n\nBest regards,\nYour JUCE App",
214+
"",
215+
[] (bool success, const String& error) {
216+
if (success)
217+
Logger::writeToLog ("Email sent successfully!");
218+
else
219+
Logger::writeToLog ("Error sending email: " + error);
220+
}
221+
);
222+
*/
223+
}
224+
225+
void demonstrateCalendar()
226+
{
227+
Logger::writeToLog ("=== Google Calendar API Demo ===");
228+
229+
// Get calendar list
230+
apiManager.getCalendars ([this] (const var& data, const String& error) {
231+
if (! error.isEmpty())
232+
{
233+
Logger::writeToLog ("Error getting calendars: " + error);
234+
return;
235+
}
236+
237+
Logger::writeToLog ("Calendars: " + JSON::toString (data));
238+
239+
// Create a test event
240+
auto event = new DynamicObject();
241+
event->setProperty ("summary", "Test Event from JUCE");
242+
event->setProperty ("description", "This event was created using GoogleAPIManager");
243+
244+
// Set start time (1 hour from now)
245+
auto startTime = new DynamicObject();
246+
const Time start = Time::getCurrentTime() + RelativeTime::hours (1);
247+
startTime->setProperty ("dateTime", start.toISO8601 (true));
248+
startTime->setProperty ("timeZone", "UTC");
249+
event->setProperty ("start", var (startTime));
250+
251+
// Set end time (2 hours from now)
252+
auto endTime = new DynamicObject();
253+
const Time end = Time::getCurrentTime() + RelativeTime::hours (2);
254+
endTime->setProperty ("dateTime", end.toISO8601 (true));
255+
endTime->setProperty ("timeZone", "UTC");
256+
event->setProperty ("end", var (endTime));
257+
258+
apiManager.createEvent ("primary", var (event), [] (const var& data, const String& error) {
259+
if (! error.isEmpty())
260+
{
261+
Logger::writeToLog ("Error creating event: " + error);
262+
return;
263+
}
264+
265+
Logger::writeToLog ("Created event: " + JSON::toString (data));
266+
});
267+
});
268+
}
269+
270+
void setupUI()
271+
{
272+
addAndMakeVisible (statusLabel);
273+
statusLabel.setText ("Initialising...", dontSendNotification);
274+
statusLabel.setJustificationType (Justification::centred);
275+
276+
addAndMakeVisible (authCodeEditor);
277+
authCodeEditor.setTextToShowWhenEmpty ("Paste authorisation code here", Colours::grey);
278+
279+
addAndMakeVisible (authButton);
280+
authButton.onClick = [this]() {
281+
const String code = authCodeEditor.getText().trim();
282+
if (code.isNotEmpty())
283+
{
284+
authenticateWithCode (code);
285+
authCodeEditor.clear();
286+
}
287+
};
288+
289+
addAndMakeVisible (sheetsButton);
290+
sheetsButton.onClick = [this]() { demonstrateSheets(); };
291+
292+
addAndMakeVisible (docsButton);
293+
docsButton.onClick = [this]() { demonstrateDocs(); };
294+
295+
addAndMakeVisible (gmailButton);
296+
gmailButton.onClick = [this]() { demonstrateGmail(); };
297+
298+
addAndMakeVisible (calendarButton);
299+
calendarButton.onClick = [this]() { demonstrateCalendar(); };
300+
301+
enableButtons (false);
302+
}
303+
304+
void enableButtons (bool enabled)
305+
{
306+
sheetsButton.setEnabled (enabled);
307+
docsButton.setEnabled (enabled);
308+
gmailButton.setEnabled (enabled);
309+
calendarButton.setEnabled (enabled);
310+
}
311+
312+
//==============================================================================
313+
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GoogleAPIDemo)
314+
};

0 commit comments

Comments
 (0)