{CLOSED} A "simple" calendar view with child views

Cableguy

Expert
Licensed User
Longtime User
Hi guys...

It's my first time in this sub-forum as a post creator...
I need a view... in my case a calendar view with child views...
basically a monthly, weekly and dayly views... pretty basic BUT with a few extra features that I will later discuss as needed...
I will pay 20$ via PayPal. .. I know it's not much but the Lib would not be my property but would be published by the developer as donation ware...
 

Cableguy

Expert
Licensed User
Longtime User
20$...greeddy
For you, a real developer, 20$ is not much... almost nothing, but for someone like me, that codes for pleasure, that has never earned a single buck from apps, or any other computers related ventures... 20$ is a box of hamburgers... 5 meals... a full weeks dinner.
Plus, I'm not "buying" the LIB... I'm making the first donation with the pledge of having a say about its functionality...
You're not interested, that's "normal"... but don't question the amount I may dispose for something that I want to give away...
 

imbault

Well-Known Member
Licensed User
Longtime User
Ok, so if it's only for pleasure, it should be free.
and, yes, honestly, 20$ or nothing is likely the same, so don't ask what you want for 20$, that's what I mean, Or offer something cool, like a rapsberry PI 2
 
Last edited:

Cableguy

Expert
Licensed User
Longtime User
So, Ok... for FREE, will you create me a LIB that does what I want it to do?...
 

RandomCoder

Well-Known Member
Licensed User
Longtime User
I'm aware that @DonManfred has been looking to and is currently working on wrapping a Calendar lib. He may be able to accommodate your request, I'm presuming that his lib will be donationware like some of his others. Sorry Manfred if I've made incorrect assumptions ;)

In the meantime I'll have a look at the calendar class suggested above and see if I can make sense of it. But having known you for some time now @Cableguy, I suspect that you maybe a better programmer than me.

Regards,
RandomCoder
 

Cableguy

Expert
Licensed User
Longtime User
I'm aware that @DonManfred has been looking to and is currently working on wrapping a Calendar lib. He may be able to accommodate your request, I'm presuming that his lib will be donationware like some of his others. Sorry Manfred if I've made incorrect assumptions ;)

In the meantime I'll have a look at the calendar class suggested above and see if I can make sense of it. But having known you for some time now @Cableguy, I suspect that you maybe a better programmer than me.

Regards,
RandomCoder

I did have a few PM exchanged with Don but he ceased responding me....
I doubt a lot that I am a better programmer than you, and I do thank you for your promptness... I have started work on this "view" a few weeks ago and been on and off of it... maybe we can collaborate on this, what say you?
 
Last edited:

RandomCoder

Well-Known Member
Licensed User
Longtime User
Sounds like a plan. I'm looking at the Custom Calendar Class at the moment. The day labels are actually buttons and I've added events to these so that I know which day is pressed and the variables "nbj" and fixed value of "41" in the "PrintDate" subroutine set how many days are displayed within the month view. I've got it so that it's showing just the first week of the month by altering these variables. Therefore I reckon that with a bit of manipulation any week in the month could theoretically be shown. How do you envisage each calendar view being displayed? For instance is the week view just 7 columns filling the screen? Is day view one panel but with time slots maybe?
What did you have in mind?

I've got to go now, and won't be on again tonight but will check back tomorrow.
 

DonManfred

Expert
Licensed User
Longtime User
I did have a few PM exchanged with Don but he ceased responding me....
Not really ceased. Just dont find the time actually :-/
 

DonManfred

Expert
Licensed User
Longtime User
I will kepp you informed if i get progress on the lib...
Actually i need to learn to work with a Content-Provider which is part on the lib. In fact behind the provider stands a sqlite-database.

My problem; i never really worked with Sqlite databases in B4A (except trying the examples)!

I´m wondering if i am able to use this database from b4a with sql-commands directly or do i need to use the provider...

The point is that i actually need to fill the database with events from b4a so that the library can use this database to read the events to show

B4X:
package anywheresoftware.b4a;

import java.util.HashMap;
import java.util.List;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

public class CalendarProvider extends ContentProvider {
  
    private static final String DATABASE_NAME = "Calendar";
    private static final String EVENTS_TABLE = "events";
    private static final int DATABASE_VERSION = 4;
    private static final String  AUTHORITY = "anywheresoftware.b4a.calendarprovider";
    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/events");
    public static final Uri CONTENT_ID_URI_BASE = Uri.parse("content://" + AUTHORITY + "/events/");
    private static final UriMatcher uriMatcher;
  
    public static final String EVENT = "event";
    public static final String LOCATION = "location";
    public static final String DESCRIPTION = "description";
    public static final String START = "start";
    public static final String END = "end";
    public static final String ID = "_id";
    public static final String START_DAY = "start_day";
    public static final String END_DAY = "end_day";
    public static final String COLOR = "color";
  
    private static final HashMap<String, String> mMap;
    private DatabaseHelper DBHelper;
    private SQLiteDatabase db;
  
    private static class DatabaseHelper extends SQLiteOpenHelper{
        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            createTables(db);
        }
      
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w("CalendarProvider", "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS events");
            onCreate(db);
        }
      
        private void createTables(SQLiteDatabase db){
            db.execSQL("CREATE TABLE " + EVENTS_TABLE + "(" + ID + " integer primary key autoincrement, " +    EVENT + " TEXT, " + LOCATION + " TEXT, " + DESCRIPTION + " TEXT, "+ START + " INTEGER, "+ END + " INTEGER, " + START_DAY + " INTEGER, " + END_DAY + " INTEGER, " + COLOR +" INTEGER);");
    }
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int count = 0;
        int num = uriMatcher.match(uri);
        if(num == 1){
            count = db.delete(EVENTS_TABLE, selection,selectionArgs);
        }else if(num == 2){
            String id = uri.getPathSegments().get(1);
            count = db.delete(EVENTS_TABLE, ID + " = " + id + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        long rowID = db.insert(EVENTS_TABLE,null, values);
        Uri _uri = null;
        if(rowID > 0){
            _uri = ContentUris.withAppendedId(CONTENT_ID_URI_BASE,rowID);
            getContext().getContentResolver().notifyChange(uri,null);
          
        }else{
            throw new SQLException("Failed to insert row into " + uri);
        }
        return _uri;
    }

    @Override
    public boolean onCreate() {
        Context context = getContext();
        DBHelper = new DatabaseHelper(context);
        db = DBHelper.getWritableDatabase();
        return (db == null)? false:true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();
        sqlBuilder.setTables(EVENTS_TABLE);

        if(uriMatcher.match(uri) == 1){
            sqlBuilder.setProjectionMap(mMap);
        }else if(uriMatcher.match(uri) == 2){
            sqlBuilder.setProjectionMap(mMap);
            sqlBuilder.appendWhere(ID + "=?");
            selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,new String[] {uri.getLastPathSegment()});
        }else if(uriMatcher.match(uri) == 3){
            sqlBuilder.setProjectionMap(mMap);
            sqlBuilder.appendWhere(START + ">=? OR ");
            sqlBuilder.appendWhere(END + "<=?");
            List<String> list = uri.getPathSegments();
            String start = list.get(1);
            String end = list.get(2);
            selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,new String[] {start,end});
        }
        if(sortOrder == null || sortOrder == "")
            sortOrder = START + " COLLATE LOCALIZED ASC";
        Cursor c = sqlBuilder.query(db, projection, selection, selectionArgs,null,null, sortOrder);
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        int count = 0;
        int num = uriMatcher.match(uri);
        if(num == 1){
            count = db.update(EVENTS_TABLE, values, selection, selectionArgs);
        }else if(num == 2){
            count = db.update(EVENTS_TABLE, values, ID + " = " + uri.getPathSegments().get(1) + (!TextUtils.isEmpty(selection) ? " AND (" +
                      selection + ')' : ""),
                      selectionArgs);
        }else{
            throw new IllegalArgumentException(
                    "Unknown URI " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }
  
    static{
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(AUTHORITY,EVENTS_TABLE,1);
        uriMatcher.addURI(AUTHORITY,EVENTS_TABLE + "/#",2);
        uriMatcher.addURI(AUTHORITY, EVENTS_TABLE+"/#/#", 3);
      
        mMap = new HashMap<String, String>();
        mMap.put(ID, ID);
        mMap.put(EVENT, EVENT);
        mMap.put(START, START);
        mMap.put(LOCATION, LOCATION);
        mMap.put(DESCRIPTION, DESCRIPTION);
        mMap.put(END, END);
        mMap.put(START_DAY, START_DAY);
        mMap.put(END_DAY, END_DAY);
        mMap.put(COLOR, COLOR);
    }

}
 
Last edited:
Top